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