*** empty log message ***
[dyninst.git] / dyner / src / cmdline.y
1 %{
2 #if defined(i386_unknown_nt4_0)
3 #include <malloc.h>
4 #include <string.h>
5 #endif
6
7 #include "BPatch_thread.h"
8 #include "BPatch_image.h"
9 #include "BPatch_type.h"
10 #include "BPatch_snippet.h"
11 #include "breakpoint.h"
12
13 extern "C" {
14 void yyerror(char *s);
15 int yyparse(void);
16 }
17
18 extern BPatch_thread *appThread;
19 extern BPatch_image *appImage;
20
21 int yylex();
22
23 BPatch_snippet *parse_result;
24 parse_ret parse_type;
25
26 %}
27
28 %union {
29     int                                 ival;
30     char                                *sval;
31     BPatch_snippet                      *snippet;
32     BPatch_boolExpr                     *boolExpr;
33     BPatch_Vector<BPatch_snippet *>     *snippetList;
34     BPatch_funcCallExpr                 *funcCall;
35 };
36
37
38 %token <sval> IDENTIFIER STRING
39 %token <ival> NUMBER
40 %token ERROR IF ELSE
41 %token PLUSPLUS MINUSMINUS
42
43 %left DOT
44 %left OR
45 %left AND
46 %left EQ NOT_EQ LESS_EQ GREATER_EQ
47 %left '+' '-'
48 %left '*' '/'
49 %left COMMA
50 %left ASSIGN
51 %left SEMI
52 %left START_BLOCK END_BLOCK
53
54 %type <boolExpr> bool_expression 
55 %type <snippet> arith_expression variable_expr statement inc_decr_expr
56 %type <snippet> param
57 %type <snippetList> param_list statement_list
58 %type <funcCall> func_call
59
60
61 %%
62
63 start:
64     '(' bool_expression ')' {
65         parse_result = (BPatch_snippet *) $2;
66         parse_type = parsed_bool;
67     }
68     |
69     statement_list { parse_result = new BPatch_sequence(*$1); 
70                    parse_type = parsed_statement; 
71                    delete $1;
72                    }
73     ; 
74
75 statement_list:
76     { $$ = new BPatch_Vector<BPatch_snippet *>; }
77     | statement SEMI statement_list
78     {
79         $3->push_front($1);
80         $$ = $3;
81     }
82     ;
83
84 statement:
85         arith_expression { $$ = $1; }
86         |
87         IF '(' bool_expression ')' statement {
88              $$ = new BPatch_ifExpr(*$3, *$5);
89              delete $3;
90              delete $5;
91         }
92         |
93         IF '(' bool_expression ')' statement ELSE statement {
94              $$ = new BPatch_ifExpr(*$3, *$5, *$7);
95              delete $3;
96              delete $5;
97              delete $7;
98         }
99         ;
100
101 func_call: IDENTIFIER '(' param_list ')'
102     { 
103         BPatch_function *func;
104         func = appImage->findFunction($1);
105         if (!func) {
106             printf("unable to find function %s\n", $1);
107             free($1);
108             return 1;
109         }
110
111         free($1);
112         $$ = new BPatch_funcCallExpr(*func, *$3); 
113     }
114
115 param_list: param 
116     { 
117         $$ = new BPatch_Vector<BPatch_snippet *>; 
118         $$->push_back($1);
119     }
120     | param_list COMMA param
121     { 
122         $1->push_back($3); 
123         $$ = $1;
124     }
125     ;
126
127 param: arith_expression
128     |  STRING
129     { 
130         $$ = new BPatch_constExpr($1); 
131     }
132     ;
133     
134
135 bool_expression: arith_expression '<' arith_expression {
136         $$ = new BPatch_boolExpr(BPatch_lt, *$1, *$3);
137         delete $1;
138         delete $3;
139     }
140     |            arith_expression '>' arith_expression {
141         $$ = new BPatch_boolExpr(BPatch_gt, *$1, *$3);
142         delete $1;
143         delete $3;
144     }
145     |            arith_expression EQ arith_expression {
146         $$ = new BPatch_boolExpr(BPatch_eq, *$1, *$3);
147         delete $1;
148         delete $3;
149     }
150     |            arith_expression LESS_EQ arith_expression {
151         $$ = new BPatch_boolExpr(BPatch_le, *$1, *$3);
152         delete $1;
153         delete $3;
154     }
155     |            arith_expression GREATER_EQ arith_expression {
156         $$ = new BPatch_boolExpr(BPatch_ge, *$1, *$3);
157         delete $1;
158         delete $3;
159     }
160     |            arith_expression NOT_EQ arith_expression {
161         $$ = new BPatch_boolExpr(BPatch_ne, *$1, *$3);
162         delete $1;
163         delete $3;
164     }
165     |            bool_expression AND bool_expression  {
166         $$ = new BPatch_boolExpr(BPatch_and, *$1, *$3);
167         delete $1;
168         delete $3;
169     }
170     |            bool_expression OR bool_expression  {
171         $$ = new BPatch_boolExpr(BPatch_or, *$1, *$3);
172         delete $1;
173         delete $3;
174     }
175     ;
176
177 variable_expr:
178     IDENTIFIER {
179         BPatch_variableExpr *var = findVariable($1);
180         if (var == NULL) {
181             fprintf(stderr, "Cannot find variable: %s\n", $1);
182             free($1);
183             return 1;
184             $$ = NULL;
185         }
186         free($1);
187         $$ = var;
188     }
189     |
190     IDENTIFIER DOT IDENTIFIER {
191         bool foundField = false;
192
193         BPatch_variableExpr *var = findVariable($1);
194         if (var == NULL) {
195             fprintf(stderr, "Cannot find variable: %s\n", $1);
196             free($1);
197             return 1;
198         }
199
200         BPatch_Vector<BPatch_variableExpr *> *vars = var->getComponents();
201         if (!vars) {
202             fprintf(stderr, "is not an aggregate type: %s\n", $1);
203             free($1);
204             return 1;
205         }
206         for (int i=0; i < vars->size(); i++) {
207             if (!strcmp($3, (*vars)[i]->getName())) {
208                 $$ = (*vars)[i];
209                 foundField = true;
210             }
211         }
212
213         if (!foundField) {
214             fprintf(stderr, "%s is not a field of %s\n", $3, $1);
215             free($1);
216             return 1;
217         }
218
219         free($1);
220     }
221     ;
222
223 arith_expression: 
224     variable_expr
225     |  NUMBER     { $$ = new BPatch_constExpr($1); }
226     |            arith_expression '*' arith_expression  {
227         $$ = new BPatch_arithExpr(BPatch_times, *$1, *$3);
228         delete $1;
229         delete $3;
230     }
231     |
232     func_call { $$ = $1; }
233     |
234     variable_expr ASSIGN arith_expression {
235             $$ = new BPatch_arithExpr(BPatch_assign, *$1, *$3);
236             if ($1) delete $1;
237             if ($3) delete $3;
238     }
239
240     |            arith_expression '/' arith_expression  {
241         $$ = new BPatch_arithExpr(BPatch_divide, *$1, *$3);
242         delete $1;
243         delete $3;
244     }
245     |            arith_expression '+' arith_expression  {
246         $$ = new BPatch_arithExpr(BPatch_plus, *$1, *$3);
247         delete $1;
248         delete $3;
249     }
250     |            arith_expression '-' arith_expression  {
251         $$ = new BPatch_arithExpr(BPatch_minus, *$1, *$3);
252         delete $1;
253         delete $3;
254     }
255     |            '(' arith_expression ')' {
256         $$ = $2;
257     }
258     |  inc_decr_expr {
259         $$ = $1;
260     }
261     ;
262
263 inc_decr_expr:
264     variable_expr PLUSPLUS {
265         $$ = new BPatch_arithExpr(BPatch_assign, *$1, BPatch_arithExpr(BPatch_plus, 
266                         *$1, BPatch_constExpr(1)));
267     }
268     | PLUSPLUS variable_expr {
269         $$ = new BPatch_arithExpr(BPatch_assign, *$2, BPatch_arithExpr(BPatch_plus, 
270                         *$2, BPatch_constExpr(1)));
271     }
272     | variable_expr MINUSMINUS {
273         $$ = new BPatch_arithExpr(BPatch_assign, *$1, BPatch_arithExpr(BPatch_minus, 
274                         *$1, BPatch_constExpr(1)));
275     }
276     | MINUSMINUS variable_expr {
277         $$ = new BPatch_arithExpr(BPatch_assign, *$2, BPatch_arithExpr(BPatch_minus, 
278                         *$2, BPatch_constExpr(1)));
279     }
280 %%
281
282
283 #if 0 // For testing the parser independently
284 extern "C" void set_lex_input(char *str);
285
286 main(int argc, char *argv[])
287 {
288     int ret;
289
290     char str[512];
291     printf("here> ");
292     gets(str);
293
294     set_lex_input(str);
295
296     ret = yyparse();
297
298     printf("Returned: %d\n", ret);
299 }
300 #endif
301
302 void yyerror(char *s)
303 {
304     fprintf(stderr, "Error on command line: %s\n",s);
305 }