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