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