]> mj.ucw.cz Git - umpf.git/blob - cond.y
new changes documented
[umpf.git] / cond.y
1 %{
2
3 #include <stdio.h>
4 #include <string.h>
5 #include <ctype.h>
6
7 #include "umpf.h"
8
9 static struct tree* tree_malloc(int type);
10 static enum var_type get_var_type(char* var);
11
12 %}
13 %error-verbose
14
15 %union {
16         int n;
17         char* str;
18         struct tree* tr;        
19 }
20
21 %token <str> CONST
22 %token <n> NUM
23 %token <str> VAR
24 %token <n> KW_DISCARD
25 %token <n> KW_PIPE KW_MAIL KW_COPY KW_FILTER
26 %token '(' ')' '{' '}' ';'
27 %nonassoc KW_IF
28 %nonassoc KW_ELSE
29 %left ARROW
30 %left <n> EQ NEQ GE LE '<' '>' RE NRE
31 %left <n> '='
32 %left <n> '.'
33 %left <n> '+' '-' 
34 %left <n> '*' '/'
35 %left <n> '|'
36 %left <n> '^'
37 %left <n> '&'
38 %right <n> '!'
39 %left <n> NEG
40 %type <tr> input_init 
41 %type <tr> input 
42 %type <tr> command 
43 %type <tr> ass 
44 %type <tr> ass_right 
45 %type <tr> ass_right_p
46 %type <tr> cif
47 %type <tr> arrow 
48 %type <tr> cond
49 %type <n> rop 
50 %type <n> left
51 %type <n> right 
52 %type <tr> leaves 
53
54 %%
55 input_init: input {input_tree = $$}
56
57 ;
58 input:  /* empty */     { $$ =  tree_malloc(ST_EMPTY); }
59         | command input {       $$ = tree_malloc(ST_BLOCK); 
60                                 $$->pt.block.head = $1;
61                                 $$->pt.block.tail = $2;
62                         } 
63 ;
64
65 command:         ';' { $$ = tree_malloc(ST_EMPTY); }
66                 | '{' command input '}'         {
67                                                 $$ = tree_malloc(ST_BLOCK); 
68                                                 $$->pt.block.head = $2;
69                                                 $$->pt.block.tail = $3; 
70                                         }
71                 | '{' '}' { $$ = tree_malloc(ST_EMPTY); }
72                 | cif
73                 | ass ';' { $$ = $1; }
74                 | arrow ';' { $$ = $1; }
75                 
76         
77 ;
78
79 cif:    KW_IF cond command KW_ELSE command      { 
80                                         $$ = tree_malloc(ST_IF);
81                                         $$->pt.tif.c = $2;
82                                         $$->pt.tif.i = $3;
83                                         $$->pt.tif.e = $5;
84                                 }
85         | KW_IF cond command    { 
86                                         $$ = tree_malloc(ST_IF);
87                                         $$->pt.tif.c = $2;
88                                         $$->pt.tif.i = $3;
89                                         $$->pt.tif.e = tree_malloc(ST_EMPTY); 
90                                 }
91 ;
92
93 cond:   '!' cond {
94                                 $$ = tree_malloc(ST_COND);
95                                 $$->pt.cond.left = $2;  
96                                 $$->pt.cond.right = NULL; 
97                                 $$->pt.cond.op = $1;    
98                                 $$->pt.cond.type = OP_BOOL;     
99                 }
100         | cond '|' cond {
101                                 $$ = tree_malloc(ST_COND);
102                                 $$->pt.cond.left = $1;  
103                                 $$->pt.cond.right = $3; 
104                                 $$->pt.cond.op = $2;    
105                                 $$->pt.cond.type = OP_BOOL;     
106                         }
107         | cond '&' cond {
108                                 $$ = tree_malloc(ST_COND);
109                                 $$->pt.cond.left = $1;  
110                                 $$->pt.cond.right = $3; 
111                                 $$->pt.cond.op = $2;    
112                                 $$->pt.cond.type = OP_BOOL;     
113                         }
114         | cond '^' cond {
115                                 $$ = tree_malloc(ST_COND);
116                                 $$->pt.cond.left = $1;  
117                                 $$->pt.cond.right = $3; 
118                                 $$->pt.cond.op = $2;    
119                                 $$->pt.cond.type = OP_BOOL;     
120
121                         }
122         | '(' cond ')' { $$ = $2; }
123         | ass_right rop ass_right       {
124                                                 $$ = tree_malloc(ST_COND);
125                                                 $$->pt.cond.left = $1;  
126                                                 $$->pt.cond.right = $3; 
127                                                 $$->pt.cond.op = $2;    
128                                                 $$->pt.cond.type = OP_REL;      
129                                         }
130         | ass_right {
131                                 $$ = tree_malloc(ST_COND);
132                                 $$->pt.cond.left = $1;  
133                                 $$->pt.cond.type = JUST_BOOL;   
134                 }
135 ;
136
137 rop:    '>'
138         | '<'
139         | EQ
140         | NEQ
141         | LE
142         | GE
143         | RE
144         | NRE
145 ;
146
147 ass:
148         VAR '=' ass_right_p     {
149                                         $$ = tree_malloc(ST_ASS);
150
151                                         $$->pt.ass.left = tree_malloc(ST_LEAF);
152                                         $$->pt.ass.left->pt.leaf.type = L_VAR;
153                                         $$->pt.ass.left->pt.leaf.value = $1;
154                                         $$->pt.ass.left->pt.leaf.n = find_var($1, get_var_type($1), var_hash);
155                                         $$->pt.ass.right = $3;
156                                 }
157 ;
158
159 leaves:         VAR     {
160                                 $$ = tree_malloc(ST_LEAF);
161                                 $$->pt.leaf.type = L_VAR;
162                                 $$->pt.leaf.value = $1;
163                                 $$->pt.leaf.n = find_var($1, get_var_type($1), var_hash);
164                         }
165                 | CONST { 
166                                 $$ = tree_malloc(ST_LEAF);
167                                 $$->pt.leaf.type = L_CONST;
168                                 $$->pt.leaf.value = $1;
169                                 $$->pt.leaf.n = store_const($1);
170                         }
171 ;
172
173 arrow:  left ARROW right ass_right  {
174                                         $$ = tree_malloc(ST_ARROW);
175                                         $$->pt.arrow.s = $4;
176                                         $$->pt.arrow.left = $1;
177                                         $$->pt.arrow.right = $3;
178                                 }
179         | left ARROW KW_DISCARD         { //FIXME: actually left does not make sense here 
180                                         $$ = tree_malloc(ST_ARROW);
181                                         $$->pt.arrow.s = NULL;
182                                         $$->pt.arrow.left = K_EMPTY;
183                                         $$->pt.arrow.right = K_DISCARD;
184                                 }
185 ;
186
187 left:   /* empty */ { $$ = K_EMPTY;}
188         | KW_COPY { $$ = K_COPY; }
189
190 ;
191
192 right:  /* empty */ { $$ = K_EMPTY; }
193         | KW_PIPE { $$ = K_PIPE; }
194         | KW_MAIL { $$ = K_MAIL; }
195         | KW_FILTER { $$ = K_FILTER; }
196 ;
197
198 ass_right_p:    '(' ass_right ')'       {$$ = $2; }
199                 | ass_right     {$$ = $1; }
200 ;
201
202 ass_right:      leaves
203                 | ass_right '.' ass_right       {
204                                         $$ = tree_malloc(ST_OP);
205                                         $$->pt.op.op = $2;
206                                         $$->pt.op.left = $1;    
207                                         $$->pt.op.right = $3;   
208                                 }
209                 | ass_right '+' ass_right       {
210                                         $$ = tree_malloc(ST_OP);
211                                         $$->pt.op.op = $2;
212                                         $$->pt.op.left = $1;    
213                                         $$->pt.op.right = $3;   
214                                 }
215                 | ass_right '-' ass_right       {
216                                         $$ = tree_malloc(ST_OP);
217                                         $$->pt.op.op = $2;
218                                         $$->pt.op.left = $1;    
219                                         $$->pt.op.right = $3;   
220                                 }
221                 | ass_right '*' ass_right       {
222                                         $$ = tree_malloc(ST_OP);
223                                         $$->pt.op.op = $2;
224                                         $$->pt.op.left = $1;    
225                                         $$->pt.op.right = $3;   
226                                 }
227                 | ass_right '/' ass_right       {
228                                         $$ = tree_malloc(ST_OP);
229                                         $$->pt.op.op = $2;
230                                         $$->pt.op.left = $1;    
231                                         $$->pt.op.right = $3;   
232                                 }
233                 | '-' ass_right %prec NEG {
234                                         $$ = tree_malloc(ST_OP);
235                                         $$->pt.op.op = $1;
236                                         $$->pt.op.left = tree_malloc(ST_LEAF);
237                                         $$->pt.op.left->pt.leaf.type = L_CONST;
238                                         $$->pt.op.left->pt.leaf.value = "0";
239                                         $$->pt.op.left->pt.leaf.n = 
240                                                         store_const("0");
241                                         $$->pt.op.right = $2;   
242                         }
243 ;
244
245 %%
246
247 struct tree* 
248 tree_malloc(int type)
249 {
250         struct tree* temp;
251         temp = xmalloc(sizeof (struct tree));
252         temp->st=type;
253
254         return temp;
255 }
256
257 enum var_type
258 get_var_type(char* var)
259 {
260         int upper = 0;
261         int lower = 0;
262
263         if (islower(*var))
264                 return VAR_USER;
265
266         while (*var) {
267                 if (isupper(*var))      
268                         upper++;
269                 if (islower(*var))
270                         lower++;
271                 var++;
272         }
273         if (upper && lower)
274                 return VAR_HEADER;
275
276         return VAR_INTERN;
277 }
278
279 void
280 yyerror (char const *s)
281 {
282         fprintf (stderr, "Line %d: %s\n Saving your e-mail to default mailbox %s\n", 
283                 line, s, default_mailbox);
284         longjmp(env, 1);
285 }