]> mj.ucw.cz Git - umpf.git/blob - cond.y
parsing conditions
[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
17 struct tree {
18         enum {
19                 ST_IF,
20                 ST_COND,
21                 ST_BLOCK,
22                 ST_ASS,
23                 ST_LEAF,
24                 ST_EMPTY
25         } st;
26         union {
27                 struct {
28                         struct tree* c;
29                         struct tree* i;
30                         struct tree* e; 
31                 } tif;
32
33                 struct {
34                         int op; 
35                         struct tree* left;
36                         struct tree* right;
37                 } cond;
38
39                 struct {
40                         struct tree* head;
41                         struct tree* tail;
42                 } block;
43
44                 struct {
45                         struct tree* left;
46                         struct tree* right;
47                 } ass;
48
49                 struct {
50                         enum {
51                                 L_VAR,
52                                 L_CONST,
53                                 L_NUM
54                         } type;
55                         union {
56                                 char* s;
57                                 int n;
58                         } value;
59                 } leaf;
60
61         } pt;
62 };
63
64 %}
65
66 %union {
67         int n;
68         char* str;
69         struct tree* tr;        
70 }
71
72 %token <str> CONST
73 %token <n> NUM
74 %token <str> VAR
75 %token KW_PIPE KW_MAIL KW_COPY
76 %token '(' ')' '{' '}' ';'
77 %left KW_ELSE
78 %left KW_IF
79 %left ARROW
80 %left <n> EQ NEQ GE LE '<' '>' RE NRE
81 %left '+' '-' 
82 %left '*' '/'
83 %left <n> '|'
84 %left <n> '^'
85 %left <n> '&'
86 %left <n> '!'
87 %left '='
88 %type <tr> input 
89 %type <tr> command 
90 %type <tr> next 
91 %type <tr> ass 
92 %type <tr> ass_right 
93 %type <tr> cif
94 %type <tr> cond
95 %type <n> rop 
96
97 %%
98 input:  /* empty */     { $$ = NULL }
99         | command input {       $$ = tree_malloc(ST_BLOCK); 
100                                 $$->pt.block.head = $1;
101                                 $$->pt.block.tail = $2; 
102                         } 
103 ;
104
105 command:         ';' { $$ = tree_malloc(ST_EMPTY); }
106                 | '{' command next '}'  {
107                                                 $$ = tree_malloc(ST_BLOCK); 
108                                                 $$->pt.block.head = $2;
109                                                 $$->pt.block.tail = $3; 
110                                         }
111                 | '{' '}' { $$ = NULL }
112                 | cif { $$ = $1 }
113                 | ass ';' { $$ = $1}
114                 
115         
116 ;
117
118 next:   /* empty */ {$$ = NULL}
119         | command
120         
121
122 ;
123
124 cif:    KW_IF cond command KW_ELSE command      { 
125                                         $$ = tree_malloc(ST_IF);
126                                         $$->pt.tif.c = $2;
127                                         $$->pt.tif.i = $3;
128                                         $$->pt.tif.e = $5;
129                                 }
130         | KW_IF cond command    { 
131                                         $$ = tree_malloc(ST_IF);
132                                         $$->pt.tif.c = $2;
133                                         $$->pt.tif.i = $3;
134                                         $$->pt.tif.e = NULL;
135                                 }
136 ;
137
138 cond:   '!' cond {
139                                 $$ = tree_malloc(ST_COND);
140                                 $$->pt.cond.left = $2;  
141                                 $$->pt.cond.right = NULL;       
142                                 $$->pt.cond.op = $1;    
143
144                 }
145         | cond '|' cond {
146                                 $$ = tree_malloc(ST_COND);
147                                 $$->pt.cond.left = $1;  
148                                 $$->pt.cond.right = $3; 
149                                 $$->pt.cond.op = $2;    
150
151                         }
152         | cond '&' cond {
153                                 $$ = tree_malloc(ST_COND);
154                                 $$->pt.cond.left = $1;  
155                                 $$->pt.cond.right = $3; 
156                                 $$->pt.cond.op = $2;    
157
158                         }
159         | cond '^' cond {
160                                 $$ = tree_malloc(ST_COND);
161                                 $$->pt.cond.left = $1;  
162                                 $$->pt.cond.right = $3; 
163                                 $$->pt.cond.op = $2;    
164
165                         }
166         | '(' cond ')' { $$ = $2; }
167         | ass_right rop ass_right       {
168                                                 $$ = tree_malloc(ST_COND);
169                                                 $$->pt.cond.left = $1;  
170                                                 $$->pt.cond.right = $3; 
171                                                 $$->pt.cond.op = $2;    
172                                         }
173 ;
174
175 rop:    '>'
176         | '<'
177         | EQ
178         | NEQ
179         | LE
180         | GE
181         | RE
182         | NRE
183 ;
184
185 ass:
186         VAR '=' ass_right       {
187                                         $$ = tree_malloc(ST_ASS);
188
189                                         $$->pt.ass.left = tree_malloc(ST_LEAF);
190                                         $$->pt.ass.left->pt.leaf.type = L_VAR;
191                                         $$->pt.ass.left->pt.leaf.value.s = $1;
192
193                                         $$->pt.ass.right = $3;
194                                 }
195 ;
196
197 ass_right:      NUM     { 
198                                 $$ = tree_malloc(ST_LEAF);
199                                 $$->pt.leaf.type = L_NUM;
200                                 $$->pt.leaf.value.n = $1;
201                         }
202                 | VAR   {
203                                 $$ = tree_malloc(ST_LEAF);
204                                 $$->pt.leaf.type = L_VAR;
205                                 $$->pt.leaf.value.s = $1;
206                         }
207                 | CONST {
208                                 $$ = tree_malloc(ST_LEAF);
209                                 $$->pt.leaf.type = L_CONST;
210                                 $$->pt.leaf.value.s = $1;
211                         }
212
213 ;
214
215 %%
216
217 struct tree* 
218 tree_malloc(int type)
219 {
220         struct tree* temp;
221         temp = xmalloc(sizeof (struct tree));
222         temp->st=type;
223
224         return temp;
225 }
226
227 int 
228 regex_cmp(char* s, char* r)
229 {
230         pcre *brum;
231         int erroroffset;
232         const char* error;
233         int ovector[OVECCOUNT];
234         
235         brum = pcre_compile(r,0,&error,&erroroffset,NULL);
236         if (!brum)
237                 return -1;
238         
239         int res = pcre_exec(brum,NULL,s,strlen(s),0,0,ovector,OVECCOUNT);
240         pcre_free(brum);
241
242         return res;
243 }
244
245 void
246 yyerror (char const *s)
247 {
248         fprintf (stderr, "%s\n", s);
249 }
250
251 int
252 main(void)
253 {
254 //      yydebug=1;
255         return yyparse ();
256 }