]> mj.ucw.cz Git - umpf.git/blob - cond.y
e69668b30b7fc2a94264b545b21c3e4bf1cfe781
[umpf.git] / cond.y
1 %{
2
3 #include <stdio.h>
4 #include <string.h>
5 #include <pcre.h>
6
7 #include "lex.h"
8
9 #define OVECCOUNT 3
10
11 int yylex (void);
12 void yyerror (char const *);
13
14 int regex_cmp(char* s, char* r);
15 struct tree* tree_malloc(int type);
16 void print_tree(struct tree* t, int ind);
17
18 struct tree {
19         enum {
20                 ST_IF,
21                 ST_COND,
22                 ST_BLOCK,
23                 ST_ASS,
24                 ST_LEAF,
25                 ST_EMPTY
26         } st;   /* subtree type */
27         union {
28                 struct {
29                         struct tree* c; /* condition */
30                         struct tree* i; /* if */
31                         struct tree* e; /* else */
32                 } tif;
33
34                 struct {
35                         int op;
36                         struct tree* left;
37                         struct tree* right;
38                 } cond; /* binary operator */
39
40                 struct {
41                         struct tree* head;
42                         struct tree* tail;
43                 } block;
44
45                 struct {
46                         struct tree* left;
47                         struct tree* right;
48                 } ass;
49
50                 struct {
51                         enum {
52                                 L_VAR,
53                                 L_CONST,
54                                 L_NUM
55                         } type;
56                         union {
57                                 char* s;
58                                 int n;
59                         } value;
60                 } leaf;
61
62         } pt;
63 };
64
65 struct tree* input_tree;
66
67 %}
68
69 %union {
70         int n;
71         char* str;
72         struct tree* tr;        
73 }
74
75 %token <str> CONST
76 %token <n> NUM
77 %token <str> VAR
78 %token KW_PIPE KW_MAIL KW_COPY
79 %token '(' ')' '{' '}' ';'
80 %nonassoc KW_IF
81 %nonassoc KW_ELSE
82 %left ARROW
83 %left <n> EQ NEQ GE LE '<' '>' RE NRE
84 %left '='
85 %left '.'
86 %left '+' '-' 
87 %left '*' '/'
88 %left <n> '|'
89 %left <n> '^'
90 %left <n> '&'
91 %left <n> '!'
92 %type <tr> input 
93 %type <tr> command 
94 %type <tr> next 
95 %type <tr> ass 
96 %type <tr> ass_right 
97 %type <tr> cif
98 %type <tr> cond
99 %type <n> rop 
100
101 %%
102 input:  /* empty */     { $$ = input_tree = NULL; }
103         | command input {       $$ = tree_malloc(ST_BLOCK); 
104                                 $$->pt.block.head = $1;
105                                 $$->pt.block.tail = $2;
106
107                                 input_tree = $$;
108                         } 
109 ;
110
111 command:         ';' { $$ = tree_malloc(ST_EMPTY); }
112                 | '{' command next '}'  {
113                                                 $$ = tree_malloc(ST_BLOCK); 
114                                                 $$->pt.block.head = $2;
115                                                 $$->pt.block.tail = $3; 
116                                         }
117                 | '{' '}' { $$ = tree_malloc(ST_EMPTY); }
118                 | cif
119                 | ass ';' { $$ = $1}
120                 
121         
122 ;
123
124 next:   /* empty */ {$$ = NULL}
125         | command
126         
127
128 ;
129
130 cif:    KW_IF cond command KW_ELSE command      { 
131                                         $$ = tree_malloc(ST_IF);
132                                         $$->pt.tif.c = $2;
133                                         $$->pt.tif.i = $3;
134                                         $$->pt.tif.e = $5;
135                                 }
136         | KW_IF cond command    { 
137                                         $$ = tree_malloc(ST_IF);
138                                         $$->pt.tif.c = $2;
139                                         $$->pt.tif.i = $3;
140                                         $$->pt.tif.e = NULL;
141                                 }
142 ;
143
144 cond:   '!' cond {
145                                 $$ = tree_malloc(ST_COND);
146                                 $$->pt.cond.left = $2;  
147                                 $$->pt.cond.right = NULL;       
148                                 $$->pt.cond.op = $1;    
149
150                 }
151         | cond '|' cond {
152                                 $$ = tree_malloc(ST_COND);
153                                 $$->pt.cond.left = $1;  
154                                 $$->pt.cond.right = $3; 
155                                 $$->pt.cond.op = $2;    
156
157                         }
158         | cond '&' cond {
159                                 $$ = tree_malloc(ST_COND);
160                                 $$->pt.cond.left = $1;  
161                                 $$->pt.cond.right = $3; 
162                                 $$->pt.cond.op = $2;    
163
164                         }
165         | cond '^' cond {
166                                 $$ = tree_malloc(ST_COND);
167                                 $$->pt.cond.left = $1;  
168                                 $$->pt.cond.right = $3; 
169                                 $$->pt.cond.op = $2;    
170
171                         }
172         | '(' cond ')' { $$ = $2; }
173         | ass_right rop ass_right       {
174                                                 $$ = tree_malloc(ST_COND);
175                                                 $$->pt.cond.left = $1;  
176                                                 $$->pt.cond.right = $3; 
177                                                 $$->pt.cond.op = $2;    
178                                         }
179 ;
180
181 rop:    '>'
182         | '<'
183         | EQ
184         | NEQ
185         | LE
186         | GE
187         | RE
188         | NRE
189 ;
190
191 ass:
192         VAR '=' ass_right       {
193                                         $$ = tree_malloc(ST_ASS);
194
195                                         $$->pt.ass.left = tree_malloc(ST_LEAF);
196                                         $$->pt.ass.left->pt.leaf.type = L_VAR;
197                                         $$->pt.ass.left->pt.leaf.value.s = $1;
198
199                                         $$->pt.ass.right = $3;
200                                 }
201 ;
202
203 ass_right:      NUM     { 
204                                 $$ = tree_malloc(ST_LEAF);
205                                 $$->pt.leaf.type = L_NUM;
206                                 $$->pt.leaf.value.n = $1;
207                         }
208                 | VAR   {
209                                 $$ = tree_malloc(ST_LEAF);
210                                 $$->pt.leaf.type = L_VAR;
211                                 $$->pt.leaf.value.s = $1;
212                         }
213                 | CONST {
214                                 $$ = tree_malloc(ST_LEAF);
215                                 $$->pt.leaf.type = L_CONST;
216                                 $$->pt.leaf.value.s = $1;
217                         }
218
219 ;
220
221 %%
222
223 struct tree* 
224 tree_malloc(int type)
225 {
226         struct tree* temp;
227         temp = xmalloc(sizeof (struct tree));
228         temp->st=type;
229
230         return temp;
231 }
232
233 int 
234 regex_cmp(char* s, char* r)
235 {
236         pcre *brum;
237         int erroroffset;
238         const char* error;
239         int ovector[OVECCOUNT];
240         
241         brum = pcre_compile(r,0,&error,&erroroffset,NULL);
242         if (!brum)
243                 return -1;
244         
245         int res = pcre_exec(brum,NULL,s,strlen(s),0,0,ovector,OVECCOUNT);
246         pcre_free(brum);
247
248         return res;
249 }
250
251 void
252 yyerror (char const *s)
253 {
254         fprintf (stderr, "%s\n", s);
255 }
256
257 void
258 print_ind(int num, char c)
259 {
260         int i;
261
262         for (i = 0; i < num; i++){
263                 putchar(c);
264         }
265 }
266
267 void
268 print_tree(struct tree* t, int ind)
269 {
270         if (!t)
271                 return; 
272
273         switch (t->st){
274                 case ST_IF:
275                         print_ind(ind,' ');
276                         puts("if");
277                         print_tree(t->pt.tif.c,ind+1);
278                         print_ind(ind,' ');
279                         puts("then");
280                         print_tree(t->pt.tif.i,ind+1);
281                         print_ind(ind,' ');
282                         puts("else");
283                         print_tree(t->pt.tif.e,ind+1);
284                         break;
285                 case ST_COND:
286 #define UPPER(a) ((a) >> 8)
287 #define LOWER(a) ((a) & 0xFF)
288                         print_tree(t->pt.cond.left, ind+1);
289                         print_ind(ind,' ');
290
291                         if (UPPER(t->pt.cond.op) > 0)
292                                 putchar(UPPER(t->pt.cond.op));
293                         putchar(LOWER(t->pt.cond.op));
294                         putchar('\n'); 
295                         print_tree(t->pt.cond.right, ind+1);    
296                         break;
297                 case ST_BLOCK:
298                         print_tree(t->pt.block.head,ind);
299                         print_tree(t->pt.block.tail,ind);
300                         break;
301                 case ST_ASS:
302                         print_tree(t->pt.ass.left, ind+1);
303                         print_ind(ind,' ');     
304                         puts("=");
305                         print_tree(t->pt.ass.right, ind+1);
306                         break;
307                 case ST_LEAF:
308                         print_ind(ind, ' ');
309                         switch (t->pt.leaf.type){
310                                 case L_VAR:
311                                         putchar('$');
312                                 case L_CONST:
313                                         puts(t->pt.leaf.value.s);
314                                         break;
315                                 case L_NUM:
316                                         printf("%d\n",t->pt.leaf.value.n);
317                                         break;
318                         }
319                         break;
320                 case ST_EMPTY:
321                         break;  
322
323
324         }
325 }
326
327
328 int
329 main(void)
330 {
331         yydebug=1;
332         yyparse ();
333
334         print_tree(input_tree,0);
335         return 0;
336 }