revert runtime file.
[repair.git] / Repair / RepairInterpreter / aparser.cc
1 #include <string.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include "aparser.h"
5 #include "list.h"
6 #include "common.h"
7 #include "token.h"
8 #include "amodel.h"
9 #include "omodel.h"
10 #include "model.h"
11
12 AParser::AParser(Reader *r) {
13   reader=r;
14 }
15
16 Rule * AParser::parserule() {
17   Token token=reader->peakahead();
18   while(token.token_type==TOKEN_EOL) {
19     skiptoken();
20     token=reader->peakahead();
21   }
22   if (token.token_type==TOKEN_EOF)
23     return NULL;
24   bool delay=false;bool staticrule=false;
25   if (token.token_type==TOKEN_DELAY||token.token_type==TOKEN_STATIC) {
26     /* both shouldn't be allowed..doesn't make sense...*/
27     if(token.token_type==TOKEN_DELAY)
28       delay=true;
29     else
30       staticrule=true;
31     skiptoken();
32     token=reader->peakahead();
33   }
34   Rule *c;
35   /*Get Quantifiers*/
36   if (token.token_type==TOKEN_OPENBRACK) {
37     skiptoken();
38     c=parsequantifiers();
39     needtoken(TOKEN_COMMA);
40   } else c=new Rule();
41   if (delay)
42     c->setdelay();
43   if (staticrule) {
44     int count=0;
45     for(int i=0;i<c->numquants();i++) {
46       AQuantifier *aq=c->getquant(i);
47       switch(aq->gettype()) {
48       case AQUANTIFIER_SING:
49         if (count>=1)
50           error();
51         count++;
52         break;
53       case AQUANTIFIER_RANGE:
54         break;
55       default:
56         error();
57       }
58     }
59     c->setstatic();
60   }
61   
62   /*Peek ahead to see if sizeof*/
63   c->setstatementa(parsestatementa(false));
64   needtoken(TOKEN_IMPLIES);
65   c->setstatementb(parsestatementb());
66   return c;
67 }
68
69 TypeEle * AParser::parsetypeele() {
70   Token type=reader->readnext();
71   needtoken(TOKEN_OPENPAREN);
72   List *list=new List();
73   while(true) {
74     Token token=reader->peakahead();
75     switch(token.token_type) {
76     case TOKEN_CLOSEPAREN: {
77       skiptoken();
78       AElementexpr** larray=new AElementexpr* [list->size()];
79       list->toArray((void **)larray);
80       TypeEle *t=new TypeEle(copystr(type.str),list->size(),larray);
81       delete(list);
82       return t;
83     }
84     default:
85       list->addobject(parseaelementexpr(false));
86       if (reader->peakahead().token_type!=TOKEN_CLOSEPAREN)
87         needtoken(TOKEN_COMMA);
88       break;
89     }
90   }
91 }
92
93 Type * AParser::parsetype() {
94   Token type=reader->readnext();
95   needtoken(TOKEN_OPENPAREN);
96   List *list=new List();
97   while(true) {
98     Token token=reader->readnext();
99     switch(token.token_type) {
100     case TOKEN_CLOSEPAREN:
101       {
102       Label** larray=new Label* [list->size()];
103       list->toArray((void **)larray);
104       Type *t=new Type(copystr(type.str),list->size(),larray);
105       delete(list);
106       return t;
107       }
108     default:
109       list->addobject(new Label(copystr(token.str)));
110       if (reader->peakahead().token_type!=TOKEN_CLOSEPAREN)
111         needtoken(TOKEN_COMMA);
112       break;
113     }
114   }
115 }
116
117 Statementa * AParser::parsestatementa(bool flag) {
118   Statementa * oldst=NULL;
119   AElementexpr *oldee=NULL;
120   int eeflag=-1;
121   int joinflag=-1;
122   while(true) {
123     Token token=reader->peakahead();
124     switch(token.token_type) {
125     case TOKEN_EOL:
126       error();
127     case TOKEN_OPENPAREN:
128       {
129         skiptoken();
130         Statementa *st=parsestatementa(false);
131         if (flag)
132           return st;
133         if (oldst==NULL) {
134           oldst=st;
135         } else {
136           if (joinflag==TOKEN_AND) {
137             oldst=new Statementa(oldst, st, STATEMENTA_AND);
138           } else if (joinflag==TOKEN_OR) {
139             oldst=new Statementa(oldst, st, STATEMENTA_OR);       
140           } else {
141             error();
142           }
143           joinflag=-1;
144         }
145       }
146       break;
147     case TOKEN_IMPLIES:
148       return oldst;
149     case TOKEN_CLOSEPAREN:
150       skiptoken();
151       return oldst;
152     case TOKEN_AND:
153       skiptoken();
154       if (oldst==NULL) error();
155       joinflag=TOKEN_AND;
156       break;
157     case TOKEN_OR:
158       skiptoken();
159       if (oldst==NULL) error();
160       joinflag=TOKEN_OR;
161       break;
162     case TOKEN_TRUE:
163       {
164         skiptoken();
165         Statementa *st=new Statementa();
166         if (flag)
167           return st;
168         if (oldst==NULL) {
169           oldst=st;
170         } else {
171           if (joinflag==TOKEN_AND) {
172             oldst=new Statementa(oldst, st, STATEMENTA_AND);
173           } else if (joinflag==TOKEN_OR) {
174             oldst=new Statementa(oldst, st, STATEMENTA_OR);       
175           } else {
176             error();
177           }
178           joinflag=-1;
179         }
180       }
181       break;
182     case TOKEN_NOT:
183       {
184         skiptoken();
185         Statementa * st=new Statementa(parsestatementa(true));
186         if (flag)
187           return st;
188         if (oldst==NULL) {
189           oldst=st;
190         } else {
191           if (joinflag==TOKEN_AND) {
192             oldst=new Statementa(oldst, st, STATEMENTA_AND);
193           } else if (joinflag==TOKEN_OR) {
194             oldst=new Statementa(oldst, st, STATEMENTA_OR);
195           } else {
196             error();
197           }
198           joinflag=-1;
199         }
200       }
201       break;
202     case TOKEN_IN: {
203       skiptoken();
204       Set *s=parseset();
205       if (oldee==NULL||eeflag!=-1)
206         error();
207       Statementa * st=new Statementa(oldee,s);
208       if (flag)
209         return st;
210       oldee=NULL;
211       if (oldst==NULL) {
212         oldst=st;
213       } else {
214         if (joinflag==TOKEN_AND) {
215           oldst=new Statementa(oldst, st, STATEMENTA_AND);
216         } else if (joinflag==TOKEN_OR) {
217           oldst=new Statementa(oldst, st, STATEMENTA_OR);
218         } else {
219           error();
220         }
221         joinflag=-1;
222       }
223     }
224     break;
225     case TOKEN_ISVALID: {
226       if (oldee!=NULL) error();
227       skiptoken();
228       needtoken(TOKEN_OPENPAREN);
229       AElementexpr *ae=parseaelementexpr(false);
230       Token t=reader->peakahead();
231       char *type=NULL;
232       if (t.token_type==TOKEN_COMMA) {
233         skiptoken();
234         Token t2=reader->readnext();
235         type=copystr(t2.str);
236       }
237       Statementa *st=new Statementa(ae, type);
238       needtoken(TOKEN_CLOSEPAREN);
239       if (flag)
240         return st;
241       if (oldst==NULL) {
242         oldst=st;
243       } else {
244         if (joinflag==TOKEN_AND) {
245           oldst=new Statementa(oldst, st, STATEMENTA_AND);
246         } else if (joinflag==TOKEN_OR) {
247           oldst=new Statementa(oldst, st, STATEMENTA_OR);
248         } else {
249           error();
250         }
251         joinflag=-1;
252       }
253     }
254       break;
255     case TOKEN_EQUALS:
256       skiptoken();
257       if (oldee==NULL) error();
258       eeflag=STATEMENTA_EQUALS;
259       break;
260     case TOKEN_LT:
261       skiptoken();
262       if (oldee==NULL) error();
263       eeflag=STATEMENTA_LT;
264       break;
265     default:
266       if ((oldee!=NULL) && (eeflag==-1))
267         error();
268       else if ((oldee==NULL)&&(eeflag==-1))
269         oldee=parseaelementexpr(false);
270       else {
271         /*oldee!=NULL, and joinee!=-1*/
272         Statementa * sa=new Statementa(oldee, parseaelementexpr(false), eeflag);
273         eeflag=-1;
274         oldee=NULL;
275         if (flag) return sa;
276         if (oldst==NULL) {
277           oldst=sa;
278         } else {
279           if (joinflag==TOKEN_AND) {
280             oldst=new Statementa(oldst, sa, STATEMENTA_AND);
281           } else if (joinflag==TOKEN_OR) {
282             oldst=new Statementa(oldst, sa, STATEMENTA_OR);       
283           } else {
284             error();
285           }
286           joinflag=-1;
287         }
288       }
289       break;
290     }
291   }
292 }
293
294 AElementexpr * AParser::checkdot(AElementexpr * incoming) {
295   Token tdot=reader->peakahead();
296   if (tdot.token_type!=TOKEN_DOT) return incoming;
297   skiptoken();
298   Token tfield=reader->readnext();
299   Token tpeak=reader->peakahead();
300   if (tpeak.token_type==TOKEN_OPENBRACK) {
301     skiptoken();
302     AElementexpr *index=parseaelementexpr(false);
303     return checkdot(new AElementexpr(incoming, new Field(copystr(tfield.str)),index));
304   } else {
305     return checkdot(new AElementexpr(incoming, new Field(copystr(tfield.str))));
306   }
307 }
308
309 AElementexpr * AParser::parseaelementexpr(bool isquant) {
310   AElementexpr *oldee=NULL;
311   int joinop=-1;
312   while(true) {
313   Token t=reader->peakahead();
314   switch(t.token_type) {
315   case TOKEN_LITERAL:
316     {
317       if ((joinop==-1)&&(oldee!=NULL))
318         return oldee;
319       skiptoken();
320       needtoken(TOKEN_OPENPAREN);
321       Token literal=reader->readnext();
322       needtoken(TOKEN_CLOSEPAREN);
323       if (oldee==NULL)
324         oldee=new AElementexpr(new Literal(copystr(literal.str)));
325       else {
326         if (joinop!=-1) {
327           oldee=new AElementexpr(oldee,new AElementexpr(new Literal(copystr(literal.str))),joinop);
328           joinop=-1;
329         } else error();
330       }
331       break;
332     }
333   case TOKEN_CAST:
334     {
335       if ((joinop==-1)&&(oldee!=NULL))
336         return oldee;
337       skiptoken();
338       needtoken(TOKEN_OPENPAREN);
339       Token casttype=reader->readnext();
340       needtoken(TOKEN_COMMA);
341       AElementexpr *ee=parseaelementexpr(false);
342       AElementexpr *tee=checkdot(new AElementexpr(copystr(casttype.str),ee));
343       if (oldee==NULL)
344         oldee=tee;
345       else {
346         if (joinop!=-1) {
347           oldee=new AElementexpr(oldee,tee,joinop);
348           joinop=-1;
349         } else error();
350       }
351       break;
352     }
353    
354   case TOKEN_OPENPAREN:
355     {
356       if ((joinop==-1)&&(oldee!=NULL))
357         return oldee;
358       skiptoken();
359       AElementexpr *ee=checkdot(parseaelementexpr(false));
360       if (oldee==NULL)
361         oldee=ee;
362       else {
363         if (joinop!=-1) {
364           oldee=new AElementexpr(oldee,ee,joinop);
365           joinop=-1;
366         } else error();
367       }
368       break;
369     }
370   case TOKEN_CLOSEBRACK:
371     if (isquant)
372       return oldee;
373     skiptoken();
374     return oldee;
375   case TOKEN_CLOSEPAREN:
376     skiptoken();
377     return oldee;
378   case TOKEN_SUB:
379     skiptoken();
380     if ((oldee!=NULL)&&(joinop==-1))
381       joinop=AELEMENTEXPR_SUB;
382     else
383       error();
384     break;
385   case TOKEN_ADD:
386     skiptoken();
387     if ((oldee!=NULL)&&(joinop==-1))
388       joinop=AELEMENTEXPR_ADD;
389     else
390       error();
391     break;
392   case TOKEN_MULT:
393     skiptoken();
394     if ((oldee!=NULL)&&(joinop==-1))
395       joinop=AELEMENTEXPR_MULT;
396     else
397       error();
398     break;
399   case TOKEN_DIV:
400     skiptoken();
401     if ((oldee!=NULL)&&(joinop==-1))
402       joinop=AELEMENTEXPR_DIV;
403     else
404       error();
405     break;
406   case TOKEN_NULL:
407     if ((joinop==-1)&&(oldee!=NULL))
408       return oldee;
409     skiptoken();
410     if (oldee==NULL)
411       oldee=checkdot(new AElementexpr());
412     else {
413       if (joinop!=-1) {
414         oldee=new AElementexpr(oldee,checkdot(new AElementexpr()),joinop);
415         joinop=-1;
416       } else error();
417     }
418     break;
419   default:
420     if ((joinop==-1)&&(oldee!=NULL))
421       return oldee;
422     skiptoken();
423     if (oldee==NULL)
424       oldee=checkdot(new AElementexpr(new Label(copystr(t.str))));
425     else {
426       if (joinop!=-1) {
427         oldee=new AElementexpr(oldee,checkdot(new AElementexpr(new Label(copystr(t.str)))),joinop);
428         joinop=-1;
429       } else error();
430     }
431   }
432   }
433 }
434
435 Statementb * AParser::parsestatementb() {
436   Token t=reader->peakahead();
437   if (t.token_type==TOKEN_LT) {
438     skiptoken();
439     Token tpeak=reader->peakahead();
440     TypeEle *typel=NULL,*typer=NULL;
441     if (tpeak.token_type==TOKEN_OPENPAREN) {
442       skiptoken();
443       typel=parsetypeele();
444       needtoken(TOKEN_CLOSEPAREN);
445     }
446     AElementexpr *ael=parseaelementexpr(false);
447     needtoken(TOKEN_COMMA);
448     if (tpeak.token_type==TOKEN_OPENPAREN) {
449       skiptoken();
450       typer=parsetypeele();
451       needtoken(TOKEN_CLOSEPAREN);
452     }
453     AElementexpr *aer=parseaelementexpr(false);
454     needtoken(TOKEN_GT);
455     needtoken(TOKEN_IN);
456     Token setlabel=reader->readnext();
457     return new Statementb(typel,ael,typer,aer,new Setlabel(copystr(setlabel.str)));
458   }
459
460   TypeEle *type=NULL;
461   if (t.token_type==TOKEN_OPENPAREN) {
462     skiptoken();
463     type=parsetypeele();
464     needtoken(TOKEN_CLOSEPAREN);
465   }
466   AElementexpr *ae=parseaelementexpr(false);
467   needtoken(TOKEN_IN);
468   Token setlabel=reader->readnext();
469   return new Statementb(type,ae,new Setlabel(copystr(setlabel.str)));
470 }
471
472 void AParser::error() {
473   printf("ERROR\n");
474   reader->error();
475   exit(-1);
476 }
477
478 void AParser::skiptoken() {
479   reader->readnext();
480 }
481
482 void AParser::needtoken(int token) {
483   Token t=reader->readnext();
484   if (!(t.token_type==token)) {
485     printf("Needed token: ");
486     tokenname(token);
487     printf("\n Got token: %s ",t.str);
488     tokenname(t.token_type);
489     error();
490   }
491 }
492
493 Rule * AParser::parsequantifiers() {
494   bool bool_continue=true;
495   List * list=new List();
496   do {
497     Token token2=reader->readnext();
498     switch(token2.token_type) {
499     case TOKEN_CLOSEBRACK:
500       bool_continue=false;
501       break;
502     case TOKEN_FORALL:
503       list->addobject(parsequantifier());
504       break;
505     case TOKEN_FOR:
506       list->addobject(parsequantifierfor());
507     case TOKEN_COMMA:
508       break;
509     default:
510       error();
511     }
512   } while(bool_continue);
513   AQuantifier** qarray=new AQuantifier* [list->size()];
514   list->toArray((void **)qarray);
515   Rule *c=new Rule(qarray,list->size());
516   delete(list);
517   return c;
518 }
519
520 AQuantifier * AParser::parsequantifier() {
521   Token token=reader->peakahead();
522   if (token.token_type==TOKEN_LT) {
523     skiptoken();
524     Type *tl=NULL, *tr=NULL;
525     if (token.token_type==TOKEN_OPENPAREN) {
526       skiptoken();
527       tl=parsetype();
528       needtoken(TOKEN_CLOSEPAREN);
529     }
530     Token labell=reader->readnext();
531     needtoken(TOKEN_COMMA);
532
533     if (token.token_type==TOKEN_OPENPAREN) {
534       skiptoken();
535       tr=parsetype();
536       needtoken(TOKEN_CLOSEPAREN);
537     }
538     Token labelr=reader->readnext();
539
540     needtoken(TOKEN_GT);
541     needtoken(TOKEN_IN);
542     return new AQuantifier(new Label(copystr(labell.str)),tl,new Label(copystr(labelr.str)),tr,parseset());
543   } else {
544     Type *t=NULL;
545     if (token.token_type==TOKEN_OPENPAREN) {
546       skiptoken();
547       t=parsetype();
548       needtoken(TOKEN_CLOSEPAREN);
549     }
550     Token label=reader->readnext();
551     needtoken(TOKEN_IN);
552     return new AQuantifier(new Label(copystr(label.str)),t,parseset());
553   }
554 }
555
556 AQuantifier * AParser::parsequantifierfor() {
557   Token label=reader->readnext();
558   needtoken(TOKEN_EQUALS);
559   AElementexpr *lower=parseaelementexpr(false);
560   needtoken(TOKEN_TO);
561   AElementexpr *upper=parseaelementexpr(true);
562   return new AQuantifier(new Label(copystr(label.str)),lower,upper);
563 }
564
565 Set * AParser::parseset() {
566   Token label=reader->readnext();
567   if (label.token_type==TOKEN_OPENBRACE) {
568     bool bool_continue=true;
569     List * list=new List();
570     do {
571       Token token2=reader->readnext();
572       switch(token2.token_type) {
573       case TOKEN_CLOSEBRACE:
574         bool_continue=false;
575         break;
576       case TOKEN_COMMA:
577         break;
578       default:
579         list->addobject(new Literal(copystr(token2.str)));
580         break;
581       }
582     } while(bool_continue);
583     int size=list->size();
584     Literal** qarray=new Literal* [size];
585     list->toArray((void **)qarray);
586     delete(list);
587     return new Set(qarray,size);
588   } else
589     return new Set(new Setlabel(copystr(label.str)));
590 }
591