revert runtime file.
[repair.git] / Repair / RepairInterpreter / oparser.cc
1 #include <string.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include "oparser.h"
5 #include "omodel.h"
6 #include "list.h"
7 #include "common.h"
8 #include "token.h"
9
10
11 Constraint * Parser::parseconstraint() {
12   Token token=reader->peakahead();
13   while(token.token_type==TOKEN_EOL) {
14     skiptoken();
15     token=reader->peakahead();
16   }
17   if (token.token_type==TOKEN_EOF)
18     return NULL;
19   bool crash=false;
20   if (token.token_type==TOKEN_CRASH) {
21     crash=true;
22     skiptoken();
23   }
24   Constraint *c;
25   /*Get Quantifiers*/
26   if (token.token_type==TOKEN_OPENBRACK) {
27     skiptoken();
28     c=parsequantifiers();
29     needtoken(TOKEN_COMMA);
30   } else c=new Constraint();
31   /*Peek ahead to see if sizeof*/
32   c->setcrash(crash);
33   c->setstatement(parsestatement(false));
34   return c;
35 }
36
37 Statement * Parser::parsestatement(bool flag) {
38   Statement * oldst=NULL;
39   int joinflag=-1;
40   while(true) {
41     Token token=reader->peakahead();
42     switch(token.token_type) {
43     case TOKEN_EOL:
44       skiptoken();
45       return oldst;
46     case TOKEN_OPENPAREN:
47       {
48         skiptoken();
49         Statement *st=parsestatement(false);
50         if (flag)
51           return st;
52         if (oldst==NULL) {
53           oldst=st;
54         } else {
55           if (joinflag==TOKEN_AND) {
56             oldst=new Statement(oldst, st, STATEMENT_AND);
57           } else if (joinflag==TOKEN_OR) {
58             oldst=new Statement(oldst, st, STATEMENT_OR);
59           } else {
60             error();
61           }
62           joinflag=-1;
63         }
64       }
65       break;
66     case TOKEN_CLOSEPAREN:
67       skiptoken();
68       return oldst;
69     case TOKEN_AND:
70       skiptoken();
71       if (oldst==NULL) error();
72       joinflag=TOKEN_AND;
73       break;
74     case TOKEN_OR:
75       skiptoken();
76       if (oldst==NULL) error();
77       joinflag=TOKEN_OR;
78       break;
79     case TOKEN_NOT:
80       {
81         skiptoken();
82         Statement * st=new Statement(parsestatement(true));
83         if (flag)
84           return st;
85         if (oldst==NULL) {
86           oldst=st;
87         } else {
88           if (joinflag==TOKEN_AND) {
89             oldst=new Statement(oldst, st, STATEMENT_AND);
90           } else if (joinflag==TOKEN_OR) {
91             oldst=new Statement(oldst, st, STATEMENT_OR);         
92           } else {
93             error();
94           }
95           joinflag=-1;
96         }
97       }
98       break;
99     default:
100       {
101         Statement * st=new Statement(parsepredicate());
102         if (flag) return st;
103         if (oldst==NULL) {
104           oldst=st;
105         } else {
106           if (joinflag==TOKEN_AND) {
107             oldst=new Statement(oldst, st, STATEMENT_AND);
108           } else if (joinflag==TOKEN_OR) {
109             oldst=new Statement(oldst, st, STATEMENT_OR);         
110           }
111           joinflag=-1;
112         }
113       }
114     }
115   }
116 }
117
118 Elementexpr * Parser::parseelementexpr() {
119   Elementexpr *oldee=NULL;
120   int joinop=-1;
121   while(true) {
122   Token t=reader->peakahead();
123   switch(t.token_type) {
124   case TOKEN_SIZEOF:
125     {
126       if ((joinop==-1)&&(oldee!=NULL))
127         return oldee;
128       skiptoken();
129       needtoken(TOKEN_OPENPAREN);
130       Setexpr* se=parsesetexpr();
131       needtoken(TOKEN_CLOSEPAREN);
132       if (oldee==NULL)
133         oldee=new Elementexpr(se);
134       else {
135         if (joinop!=-1) {
136           oldee=new Elementexpr(oldee,new Elementexpr(se),joinop);
137           joinop=-1;
138         } else error();
139       }
140       break;
141     }
142   case TOKEN_LITERAL:
143     {
144       if ((joinop==-1)&&(oldee!=NULL))
145         return oldee;
146       skiptoken();
147       needtoken(TOKEN_OPENPAREN);
148       Token literal=reader->readnext();
149       needtoken(TOKEN_CLOSEPAREN);
150       if (oldee==NULL)
151         oldee=new Elementexpr(new Literal(copystr(literal.str)));
152       else {
153         if (joinop!=-1) {
154           oldee=new Elementexpr(oldee,new Elementexpr(new Literal(copystr(literal.str))),joinop);
155           joinop=-1;
156         } else error();
157       }
158       break;
159     }
160     /*  case TOKEN_PARAM:
161         {
162         if ((joinop==-1)&&(oldee!=NULL))
163         return oldee;
164         skiptoken();
165         needtoken(TOKEN_OPENPAREN);
166         Elementexpr *ee=parseelementexpr();
167         needtoken(TOKEN_COMMA);
168         Token number=reader->readnext();
169         needtoken(TOKEN_CLOSEPAREN);
170         
171         if (oldee==NULL)
172         oldee=new Elementexpr(ee,new Literal(copystr(number.str)));
173         else {
174         if (joinop!=-1) {
175         oldee=new Elementexpr(oldee,new Elementexpr(ee,new Literal(copystr(number.str))),joinop);
176         joinop=-1;
177         } else error();
178         }
179         
180         break;
181         } */
182   case TOKEN_OPENPAREN:
183     {
184       if ((joinop==-1)&&(oldee!=NULL))
185         return oldee;
186       skiptoken();
187       Elementexpr *ee=parseelementexpr();
188       if (oldee==NULL)
189         oldee=ee;
190       else {
191         if (joinop!=-1) {
192           oldee=new Elementexpr(oldee,ee,joinop);
193           joinop=-1;
194         } else error();
195       }
196       break;
197     }
198   case TOKEN_CLOSEPAREN:
199     skiptoken();
200     return oldee;
201     break;
202   case TOKEN_SUB:
203     skiptoken();
204     if ((oldee!=NULL)&&(joinop==-1))
205       joinop=ELEMENTEXPR_SUB;
206     else
207       error();
208     break;
209   case TOKEN_ADD:
210     skiptoken();
211     if ((oldee!=NULL)&&(joinop==-1))
212       joinop=ELEMENTEXPR_ADD;
213     else
214       error();
215     break;
216   case TOKEN_MULT:
217     skiptoken();
218     if ((oldee!=NULL)&&(joinop==-1))
219       joinop=ELEMENTEXPR_MULT;
220     else
221       error();
222     break;
223   default:
224     if ((joinop==-1)&&(oldee!=NULL))
225       return oldee;
226     skiptoken();
227     if (oldee==NULL)
228       oldee=checkdot(new Elementexpr(new Label(copystr(t.str))));
229     else {
230       if (joinop!=-1) {
231         oldee=new Elementexpr(oldee,new Elementexpr(new Label(copystr(t.str))),joinop);
232         joinop=-1;
233       } else error();
234     }
235   }
236   }
237 }
238
239 Elementexpr * Parser::checkdot(Elementexpr * incoming) {
240   Token tdot=reader->peakahead();
241   if (tdot.token_type!=TOKEN_DOT) return incoming;
242   skiptoken();
243   Token tfield=reader->readnext();
244   Token tpeak=reader->peakahead();
245   return checkdot(new Elementexpr(incoming, new Relation(copystr(tfield.str))));
246 }
247
248 Predicate * Parser::parsepredicate() {
249   Token label=reader->readnext();
250
251   if (label.token_type==TOKEN_SIZEOF) {
252     needtoken(TOKEN_OPENPAREN);
253     Setexpr * setexpr=parsesetexpr();
254     needtoken(TOKEN_CLOSEPAREN);
255     Token tokentest=reader->readnext();
256     bool greaterthan=false;
257     switch(tokentest.token_type) {
258     case TOKEN_EQUALS:
259       greaterthan=false;
260       break;
261     case TOKEN_GT:
262       greaterthan=true;
263       break;
264     default:
265       error();
266     }
267     needtoken(TOKEN_ONE);
268     return new Predicate(greaterthan, setexpr);
269   }
270
271   Token nexttoken=reader->readnext();
272   bool inverted=false;
273   switch(nexttoken.token_type) {
274   case TOKEN_DOTINV:
275     inverted=true;
276   case TOKEN_DOT:
277     {
278       Token relation=reader->readnext();
279       Token compareop=reader->readnext();
280       Valueexpr *ve=new Valueexpr(new Label(copystr(label.str)),
281                                  new Relation(copystr(relation.str)),inverted);
282       while(compareop.token_type==TOKEN_DOT||compareop.token_type==TOKEN_DOTINV) {
283         Token nrelation=reader->readnext();
284         bool invert=(compareop.token_type==TOKEN_DOTINV);
285         compareop=reader->readnext();
286         ve=new Valueexpr(ve,
287                          new Relation(copystr(nrelation.str)),invert);
288       }
289       Elementexpr * ee=parseelementexpr();
290
291       
292       switch(compareop.token_type) {
293       case TOKEN_LT:
294         return new Predicate(ve,PREDICATE_LT,ee);
295       case TOKEN_LTE:
296         return new Predicate(ve,PREDICATE_LTE,ee);
297       case TOKEN_EQUALS:
298         return new Predicate(ve,PREDICATE_EQUALS,ee);
299       case TOKEN_GTE:
300         return new Predicate(ve,PREDICATE_GTE,ee);
301       case TOKEN_GT:
302         return new Predicate(ve,PREDICATE_GT,ee);
303       default:
304         error();
305       }
306     }
307   case TOKEN_IN:
308     {
309       Setexpr * se=parsesetexpr();
310       return new Predicate(new Label(copystr(label.str)),se);
311     }
312   default:
313     error();
314   }
315 }
316
317 void Parser::error() {
318   printf("ERROR\n");
319   reader->error();
320   exit(-1);
321 }
322
323 void Parser::skiptoken() {
324   reader->readnext();
325 }
326
327 void Parser::needtoken(int token) {
328   Token t=reader->readnext();
329   if (!(t.token_type==token)) {
330     printf("Needed token: ");
331     tokenname(token);
332     printf("\n Got token: %s ",t.str);
333     tokenname(t.token_type);
334     error();
335   }
336 }
337
338 Constraint * Parser::parsequantifiers() {
339   bool bool_continue=true;
340   List * list=new List();
341   do {
342     Token token2=reader->readnext();
343     switch(token2.token_type) {
344     case TOKEN_CLOSEBRACK:
345       bool_continue=false;
346       break;
347     case TOKEN_FORALL:
348       list->addobject(parsequantifier());
349       break;
350     case TOKEN_COMMA:
351       break;
352     default:
353       error();
354     }
355   } while(bool_continue);
356   Quantifier** qarray=new Quantifier* [list->size()];
357   list->toArray((void **)qarray);
358   Constraint *c=new Constraint(qarray,list->size());
359   delete(list);
360   return c;
361 }
362
363 Quantifier * Parser::parsequantifier() {
364   Token label=reader->readnext();
365   needtoken(TOKEN_IN);
366   return new Quantifier(new Label(copystr(label.str)),parseset());
367 }
368
369 Set * Parser::parseset() {
370   Token label=reader->readnext();
371   if (label.token_type==TOKEN_OPENBRACE) {
372     bool bool_continue=true;
373     List * list=new List();
374     do {
375       Token token2=reader->readnext();
376       switch(token2.token_type) {
377       case TOKEN_CLOSEBRACE:
378         bool_continue=false;
379         break;
380       case TOKEN_COMMA:
381         break;
382       default:
383         list->addobject(new Literal(copystr(token2.str)));
384         break;
385       }
386     } while(bool_continue);
387     int size=list->size();
388     Literal** qarray=new Literal* [size];
389     list->toArray((void **)qarray);
390     delete(list);
391     return new Set(qarray,size);
392   } else
393     return new Set(new Setlabel(copystr(label.str)));
394 }
395
396 Setexpr * Parser::parsesetexpr() {
397   Token label=reader->readnext();
398   Token peak=reader->peakahead();
399   if (peak.token_type==TOKEN_DOT) {
400     skiptoken();
401     return new Setexpr(new Label(copystr(label.str)),false,new Relation(copystr(reader->readnext().str)));
402   } else if (peak.token_type==TOKEN_DOTINV) {
403     skiptoken();
404     return new Setexpr(new Label(copystr(label.str)),true,new Relation(copystr(reader->readnext().str)));
405   } else
406     return new Setexpr(new Setlabel(copystr(label.str)));
407 }
408
409 Parser::Parser(Reader *r) {
410   reader=r;
411 }