Moved makelib
[repair.git] / Repair / RepairInterpreter / cparser.cc
1 #include "cparser.h"
2 #include "token.h"
3 #include "amodel.h"
4 #include "omodel.h"
5 #include "cmodel.h"
6 #include "element.h"
7
8 CParser::CParser(Reader *r) {
9   reader=r;
10 }
11
12 AElementexpr * CParser::parseaelementexpr(bool isquant) {
13   CAElementexpr *oldee=NULL;
14   int joinop=-1;
15   while(true) {
16   Token t=reader->peakahead();
17   switch(t.token_type) {
18   case TOKEN_LITERAL:
19     {
20       if ((joinop==-1)&&(oldee!=NULL))
21         return oldee;
22       skiptoken();
23       needtoken(TOKEN_OPENPAREN);
24       Token literal=reader->readnext();
25       needtoken(TOKEN_CLOSEPAREN);
26       if (oldee==NULL)
27         oldee=new CAElementexpr(new Literal(copystr(literal.str)));
28       else {
29         if (joinop!=-1) {
30           oldee=new CAElementexpr(oldee,new CAElementexpr(new Literal(copystr(literal.str))),joinop);
31           joinop=-1;
32         } else error();
33       }
34       break;
35     }
36
37   case TOKEN_OPENPAREN:
38     {
39       if ((joinop==-1)&&(oldee!=NULL))
40         return oldee;
41       skiptoken();
42       CAElementexpr *ee=(CAElementexpr *)parseaelementexpr(false);
43       if (oldee==NULL)
44         oldee=ee;
45       else {
46         if (joinop!=-1) {
47           oldee=new CAElementexpr(oldee,ee,joinop);
48           joinop=-1;
49         } else error();
50       }
51       break;
52     }
53     
54   case TOKEN_CLOSEBRACK:
55     if (isquant)
56       return oldee;
57     // Otherwise fall through
58   case TOKEN_CLOSEPAREN:
59     skiptoken();
60     return checkdot(oldee);
61     break;
62   case TOKEN_SUB:
63     skiptoken();
64     if ((oldee!=NULL)&&(joinop==-1))
65       joinop=CAELEMENTEXPR_SUB;
66     else
67       error();
68     break;
69   case TOKEN_ADD:
70     skiptoken();
71     if ((oldee!=NULL)&&(joinop==-1))
72       joinop=CAELEMENTEXPR_ADD;
73     else
74       error();
75     break;
76   case TOKEN_SIZEOF: {
77     skiptoken();
78     needtoken(TOKEN_OPENPAREN);
79     Setexpr *sae=parsesetexpr();
80     needtoken(TOKEN_CLOSEPAREN);
81     return new CAElementexpr(sae);
82   }
83   case TOKEN_ELEMENT: {
84     skiptoken();
85     CAElementexpr *cae=(CAElementexpr *)parseaelementexpr(false);
86     needtoken(TOKEN_OF);
87     Setexpr *sae=parsesetexpr();
88     return new CAElementexpr(cae,sae);
89   }
90   case TOKEN_OF:
91     return oldee;
92   case TOKEN_MULT:
93     skiptoken();
94     if ((oldee!=NULL)&&(joinop==-1))
95       joinop=CAELEMENTEXPR_MULT;
96     else
97       error();
98     break;
99   case TOKEN_DIV:
100     skiptoken();
101     if ((oldee!=NULL)&&(joinop==-1))
102       joinop=CAELEMENTEXPR_DIV;
103     else
104       error();
105     break;
106   case TOKEN_NULL:
107     if ((joinop==-1)&&(oldee!=NULL))
108       return oldee;
109     skiptoken();
110     if (oldee==NULL)
111       oldee=checkdot(new CAElementexpr());
112     else {
113       if (joinop!=-1) {
114         oldee=new CAElementexpr(oldee,checkdot(new CAElementexpr()),joinop);
115         joinop=-1;
116       } else error();
117     }
118     break;
119   default:
120     if ((joinop==-1)&&(oldee!=NULL))
121       return oldee;
122     skiptoken();
123     if (oldee==NULL)
124       oldee=checkdot(new CAElementexpr(new Label(copystr(t.str))));
125     else {
126       if (joinop!=-1) {
127         oldee=new CAElementexpr(oldee,checkdot(new CAElementexpr(new Label(copystr(t.str)))),joinop);
128         joinop=-1;
129       } else error();
130     }
131   }
132   }
133 }
134
135 CAElementexpr * CParser::checkdot(CAElementexpr * incoming) {
136   Token tdot=reader->peakahead();
137   if (tdot.token_type!=TOKEN_DOT) return incoming;
138   skiptoken();
139   Token tfield=reader->readnext();
140   Token tpeak=reader->peakahead();
141   return new CAElementexpr(incoming, new Relation(copystr(tfield.str)));
142 }
143
144 Setexpr * CParser::parsesetexpr() {
145   Token label=reader->readnext();
146   Token peak=reader->peakahead();
147   if (peak.token_type==TOKEN_DOT) {
148     skiptoken();
149     return new Setexpr(new Label(copystr(label.str)),false,new Relation(copystr(reader->readnext().str)));
150   } else if (peak.token_type==TOKEN_DOTINV) {
151     skiptoken();
152     return new Setexpr(new Label(copystr(label.str)),true,new Relation(copystr(reader->readnext().str)));
153   } else
154   return new Setexpr(new Setlabel(copystr(label.str)));
155 }
156
157 Expr * CParser::parseexpr() {
158   Expr * oldee=NULL;
159   Field *oldf=NULL;
160   CAElementexpr *oldindex=NULL;
161   bool parselside=true;
162   while(parselside) {
163     Token t=reader->readnext();
164     switch(t.token_type) {
165     case TOKEN_DOT:
166       if (oldf!=NULL) {
167         /* do shift-pack stuff */
168         if(oldindex==NULL)
169           oldee=new Expr(oldee,oldf);
170         else
171           oldee=new Expr(oldee,oldf,oldindex);
172         oldf=NULL;
173         oldindex=NULL;
174       }
175       {
176         Token name=reader->readnext();
177         oldf=new Field(copystr(name.str));
178       }
179       break;
180     case TOKEN_OPENBRACK:
181       oldindex=(CAElementexpr *)parseaelementexpr(true);
182       needtoken(TOKEN_CLOSEBRACK);
183       break;
184     case TOKEN_CAST: {
185       if(oldee!=NULL)
186         error();
187       needtoken(TOKEN_OPENPAREN);
188       Token fld=reader->readnext();
189       needtoken(TOKEN_COMMA);
190       Expr *ex=parseexpr();
191       needtoken(TOKEN_CLOSEPAREN);
192       oldee=new Expr(copystr(fld.str),ex);
193       break;
194     }
195     case TOKEN_CLOSEPAREN:
196       if (oldf!=NULL) {
197         /* do shift-pack stuff */
198         if(oldindex==NULL)
199           oldee=new Expr(oldee,oldf);
200         else
201           oldee=new Expr(oldee,oldf,oldindex);
202         oldf=NULL;
203         oldindex=NULL;
204       }
205       return oldee;
206     default:
207       if(oldee!=NULL)
208         error();
209       oldee=new Expr(new Label(copystr(t.str)));
210     }
211   }
212   return oldee;
213 }
214
215 Statementb * CParser::parsestatementb() {
216   Expr * oldee=NULL;
217   Field *oldf=NULL;
218   CAElementexpr *oldindex=NULL;
219   bool parselside=true;
220   while(parselside) {
221     Token t=reader->readnext();
222     switch(t.token_type) {
223     case TOKEN_DOT:
224       if (oldf!=NULL) {
225         /* do shift-pack stuff */
226         if(oldindex==NULL)
227           oldee=new Expr(oldee,oldf);
228         else
229           oldee=new Expr(oldee,oldf,oldindex);
230         oldf=NULL;
231         oldindex=NULL;
232       }
233       {
234         Token name=reader->readnext();
235         oldf=new Field(copystr(name.str));
236       }
237       break;
238     case TOKEN_OPENBRACK:
239       oldindex=(CAElementexpr *)parseaelementexpr(true);
240       needtoken(TOKEN_CLOSEBRACK);
241       break;
242     case TOKEN_CAST: {
243       if(oldee!=NULL)
244         error();
245       needtoken(TOKEN_OPENPAREN);
246       Token fld=reader->readnext();
247       needtoken(TOKEN_COMMA);
248       Expr *ex=parseexpr();
249       oldee=new Expr(copystr(fld.str),ex);
250       break;
251     }
252     case TOKEN_EQUALS:
253       parselside=false;
254       if (oldf==NULL)
255         error();
256       break;
257     default:
258       if(oldee!=NULL)
259         error();
260       oldee=new Expr(new Label(copystr(t.str)));
261     }
262   }
263   CAElementexpr *rside=(CAElementexpr *)parseaelementexpr(false);
264   if (oldindex==NULL)
265     return new CStatementb(oldee,oldf,rside);
266   else
267     return new CStatementb(oldee,oldf,oldindex,rside);
268 }