OK, the parser now looks more decent.
[repair.git] / Repair / RepairCompiler / MCC / CDL.cup
1 package MCC;
2 import MCC.IR.ParseNode;
3 import MCC.IR.ParseNodeVector;
4 import java.util.*;
5
6 action code {:
7
8         public static boolean errors;
9         public static boolean debug;
10
11         // debugMessage: writes debug production message only if debug = true
12
13         void debugMessage (String production) {
14                 if (debug) {
15                         System.out.println("Applying production: " + production);
16                 }
17         }
18
19         String unescape (String str) {
20             StringBuffer sb = new StringBuffer();
21             int i;
22             // Note that we skip the first and last characters (they're "'s)
23             for (i = 1; i < str.length() - 1; i++) {
24                 if (str.charAt(i) == '\\') {
25                     i++;
26                     switch (str.charAt(i)) {
27                     case '\"':
28                         sb.append('\"');
29                         break;
30                     case '\'':
31                         sb.append('\'');
32                         break;
33                     case '\\':
34                         sb.append('\\');
35                         break;
36                     case 't':
37                         sb.append('\t');
38                         break;
39                     case 'n':
40                         sb.append('\n');
41                         break;
42                     default:
43                         System.err.print("Error in string literal: ");
44                         System.err.println(str.charAt(i));
45                         System.err.println("Aborting...");
46                         break;
47                     }
48                 } else {
49                     sb.append(str.charAt(i));
50                 }
51             }
52             return sb.toString();
53         }
54 :}
55
56 init with {: :}
57
58 parser code {:
59
60         public String filename;
61        
62         public void syntax_error (java_cup.runtime.Symbol current) {
63
64                 CUP$CDLParser$actions.errors = true;
65                 Symbol symbol = (Symbol) current;
66
67                 boolean isInteger = true;
68                 try{ 
69                    Integer.parseInt(current.value.toString());
70                 } catch(NumberFormatException e) { isInteger = false;}
71
72                 report_error(filename+":"+(symbol.line+1)+": Syntax error at column " 
73                 + (LineCount.getColumn(symbol.left)+1) +": " + current.value, current);
74
75                 if (current.value.equals("true") || isInteger)
76                    System.out.println("Did you mean literal("+current.value+")?");
77
78                 System.out.println();
79                 System.exit(0);
80         }
81
82         public void report_fatal_error (String message, Object info) {
83                 
84                  done_parsing();
85                  report_error(message, info);
86                  CUP$CDLParser$actions.errors = true;
87         }
88
89         public int curPos () {
90                 return cur_token.left;
91         }
92
93         public int curLine (int back) {
94                 Stack st = new Stack();
95                 int i;
96
97                 for (i = 0; i < back; i++) {
98                         st.push(stack.pop());
99                 }
100
101                 java_cup.runtime.Symbol s;
102                 s = (java_cup.runtime.Symbol) st.peek();
103
104                 for (i = 0; i < back; i++) {
105                         stack.push(st.pop());
106                 }
107
108                 return LineCount.getLine(s.left);
109         }
110         
111 :}
112
113 // TERMINALS /////////////////////////////////////////////////////////////
114
115     terminal BAD;
116
117     terminal String ID;
118     terminal String DECIMAL;
119     terminal String CHAR;
120     terminal String STRING;
121
122     terminal OPENBRACE;
123     terminal CLOSEBRACE;
124     terminal OPENPAREN;
125     terminal CLOSEPAREN; 
126     terminal OPENBRACKET;
127     terminal CLOSEBRACKET;
128
129     terminal ADD; 
130     terminal SUB; 
131     terminal MULT; 
132     terminal DIV;
133
134     terminal NOT;
135     terminal LT;
136     terminal GT;
137     terminal LE;
138     terminal GE;
139     terminal EQ;
140     terminal NE;
141
142
143     terminal FORALL;
144     terminal IN;
145     terminal INTEST;
146
147     terminal COMMA;
148     terminal SIZEOF;
149
150     terminal DOT;
151     terminal DOTINV;
152
153     terminal AND;
154     terminal OR;
155
156     terminal LITERAL;
157
158     terminal IMPLIES;
159     terminal TRUE;
160     terminal FALSE;
161     terminal ISVALID;
162     terminal FOR;
163     terminal TO;
164     terminal CAST;
165
166     terminal PARAM;
167     terminal STRUCTURE;
168     terminal RESERVED;
169     terminal BIT;
170     terminal BYTE;
171     terminal SHORT;
172       
173     terminal LABEL;
174     terminal INT;
175     terminal SUBTYPE;
176     terminal OF;
177
178     terminal SEMICOLON;
179     terminal COLON;
180
181     terminal SET;
182     terminal ARROW;
183     terminal MANY;
184     terminal BAR;
185
186     terminal PARTITION;
187     terminal ELEMENT;
188     terminal DELAY;
189     terminal STATIC;
190
191     terminal NULL;
192     terminal CRASH;
193
194 // NON-TERMINALS /////////////////////////////////////////////////////////
195
196 /*
197                 TYPE                    NAME
198 ------------------------------------------------------------------------*/
199 nonterminal     ParseNode               constraints;
200 nonterminal     ParseNode               constraint;
201 nonterminal     ParseNode               optcrash;
202 nonterminal     ParseNode               quantifiers;
203 nonterminal     ParseNode               quantifier;
204 nonterminal     ParseNode               set;
205 nonterminal     ParseNode               listofliterals;
206 nonterminal     ParseNode               literal;
207 nonterminal     ParseNode               body;
208 nonterminal     ParseNode               predicate;
209 nonterminal     ParseNode               setexpr;
210
211 nonterminal     ParseNode               compare;
212 nonterminal     ParseNode               expr;
213 nonterminal     ParseNode               operator;
214
215
216
217 precedence left OR;
218 precedence left AND;
219 precedence left EQ, NE; 
220 precedence left LT, LE, GE, GT;
221
222 precedence left ADD, SUB;
223 precedence left MULT, DIV;
224
225 precedence left NOT;
226
227 precedence left DOT, DOTINV;
228
229 // PRODUCTION RULES  /////////////////////////////////////////////////////
230
231 constraints ::=
232             
233         constraints:constraints constraint:constraint
234         {:
235         debugMessage(PRODSTRING);
236         constraints.addChild(constraint);
237         RESULT = constraints;
238         :}
239         
240         | constraint:constraint
241         {:
242         debugMessage(PRODSTRING);
243         ParseNode constraints = new ParseNode("constraints", parser.curLine(1));
244         constraints.addChild(constraint);
245         RESULT = constraints;
246         :}
247         ;
248
249 constraint ::=
250             
251         optcrash:crash OPENBRACKET quantifiers:quantifiers CLOSEBRACKET COMMA body:body SEMICOLON
252         {:
253         debugMessage(PRODSTRING);
254         ParseNode constraint = new ParseNode("constraint", parser.curLine(7));
255         if (crash != null) {
256                 constraint.addChild(crash);
257         }
258         if (quantifiers != null) {
259                 constraint.addChild(quantifiers);
260         }
261         constraint.addChild(body);
262         RESULT = constraint;
263         :}
264         ;
265
266 optcrash ::=
267
268          CRASH
269          {:
270          debugMessage(PRODSTRING);
271          RESULT = new ParseNode("crash", parser.curLine(1));
272          :}
273
274          | /* nothing */
275          {:
276          debugMessage(PRODSTRING);
277          RESULT = null;
278          :}
279          ;
280
281 quantifiers ::=
282             
283         quantifiers:quantifiers COMMA quantifier:quantifier
284         {:
285         debugMessage(PRODSTRING);
286         quantifiers.addChild(quantifier);
287         RESULT = quantifiers;
288         :}
289             
290         | quantifier:quantifier
291         {:
292         debugMessage(PRODSTRING);
293         ParseNode quantifiers = new ParseNode("quantifiers", parser.curLine(1));
294         quantifiers.addChild(quantifier);
295         RESULT = quantifiers;
296         :}
297             
298         | 
299         {:
300         debugMessage(PRODSTRING);
301         RESULT = null;
302         :}
303         ;       
304
305 quantifier ::= 
306            
307         FORALL ID:var IN set:set
308         {:
309         debugMessage(PRODSTRING);
310         ParseNode q = new ParseNode("quantifier", parser.curLine(4));
311         q.addChild("forall", parser.curLine(4));
312         q.addChild("var", parser.curLine(3)).addChild(var);
313         q.addChild(set);
314         RESULT = q;
315         :}
316         | FORALL LT ID:r1 COMMA ID:r2 GT IN ID:relation
317         {:
318         debugMessage(PRODSTRING);
319         ParseNode q = new ParseNode("quantifier", parser.curLine(7));
320         q.addChild("relation", parser.curLine(1)).addChild(relation);
321         q.addChild("left", parser.curLine(5)).addChild(r1);
322         q.addChild("right", parser.curLine(3)).addChild(r2);
323         RESULT = q;
324         :}
325         ;
326
327 set ::=
328     
329         ID:setname
330         {:
331         debugMessage(PRODSTRING);
332         ParseNode set = new ParseNode("set", parser.curLine(1));
333         set.addChild("name").addChild(setname);
334         RESULT = set;
335         :}
336
337         | OPENBRACE listofliterals:list CLOSEBRACE
338         {:
339         debugMessage(PRODSTRING);
340         ParseNode set = new ParseNode("set", parser.curLine(3));
341         set.addChild(list);
342         RESULT = set;
343         :}
344         ;
345     
346 listofliterals ::=
347                
348         listofliterals:list COMMA literal:literal
349         {:
350         debugMessage(PRODSTRING);
351         list.addChild(literal);
352         RESULT = list;
353         :}
354                
355         | literal:literal
356         {: 
357         debugMessage(PRODSTRING);
358         ParseNode list = new ParseNode("listofliterals", parser.curLine(1));
359         list.addChild(literal);
360         RESULT = list;
361         :}
362         ;
363
364 body ::=
365
366         body:body1 AND body:body2
367         {:
368         debugMessage(PRODSTRING);
369         ParseNode body = new ParseNode("body", parser.curLine(3));
370         body.addChild("and").addChild("left", parser.curLine(3)).addChild(body1);
371         body.getChild("and").addChild("right", parser.curLine(1)).addChild(body2);
372         RESULT = body;
373         :}
374      
375         | body:body1 OR body:body2
376         {:
377         debugMessage(PRODSTRING);
378         ParseNode body = new ParseNode("body", parser.curLine(3));
379         body.addChild("or").addChild("left", parser.curLine(3)).addChild(body1);
380         body.getChild("or").addChild("right", parser.curLine(1)).addChild(body2);
381         RESULT = body;
382         :}
383      
384         | NOT body:body1
385         {:
386         debugMessage(PRODSTRING);
387         ParseNode body = new ParseNode("body", parser.curLine(2));
388         body.addChild("not").addChild(body1);
389         RESULT = body;
390         :}
391      
392         | OPENPAREN body:body CLOSEPAREN
393         {:
394         debugMessage(PRODSTRING);
395         RESULT = body;
396         :}
397      
398         | predicate:predicate
399         {:
400         debugMessage(PRODSTRING);
401         ParseNode body = new ParseNode("body", parser.curLine(1));
402         body.addChild(predicate);
403         RESULT = body;
404         :}
405         ;
406
407 predicate ::=
408
409         expr:expr IN setexpr:setexpr
410         {:
411         debugMessage(PRODSTRING);
412         ParseNode inclusion = (new ParseNode("predicate", parser.curLine(3))).addChild("inclusion");
413         inclusion.addChild(expr);
414         inclusion.addChild(setexpr);
415         RESULT = inclusion.getRoot();
416         :}
417      
418         | expr:lexpr compare:compare expr:rexpr
419         {:
420         debugMessage(PRODSTRING);
421         ParseNode comparison = (new ParseNode("predicate", parser.curLine(3))).addChild("expr").addChild("operator");
422         comparison.addChild("op").addChild(compare);
423         comparison.addChild("left", parser.curLine(2)).addChild(lexpr);
424         comparison.addChild("right", parser.curLine(2)).addChild(rexpr);
425         RESULT = comparison.getRoot();
426         :}
427
428         ;
429
430 setexpr ::=
431         
432         ID:setname
433         {:
434         debugMessage(PRODSTRING);
435         ParseNode set = new ParseNode("setexpr", parser.curLine(1));
436         set.addChild("set").addChild(setname);
437         RESULT = set;
438         :}
439
440         | ID:var DOT ID:relation
441         {:
442         debugMessage(PRODSTRING);
443         ParseNode set = new ParseNode("setexpr", parser.curLine(3));
444         set.addChild("dot").addChild("quantifiervar", parser.curLine(3)).addChild(var);
445         set.getChild("dot").addChild("relation", parser.curLine(1)).addChild(relation);
446         RESULT = set;
447         :}
448
449         | ID:var DOTINV ID:relation
450         {:
451         debugMessage(PRODSTRING);
452         ParseNode set = new ParseNode("setexpr", parser.curLine(3));
453         set.addChild("dotinv").addChild("quantifiervar", parser.curLine(3)).addChild(var);
454         set.getChild("dotinv").addChild("relation", parser.curLine(1)).addChild(relation);
455         RESULT = set;
456         :}
457         ;
458         
459 expr ::=
460         
461         ID:var
462         {:
463         debugMessage(PRODSTRING);
464         ParseNode expr = new ParseNode("expr", parser.curLine(1));      
465         expr.addChild("var").addChild(var);
466         RESULT = expr;
467         :}
468         
469         | OPENPAREN expr:expr CLOSEPAREN 
470         {:
471         debugMessage(PRODSTRING);
472         RESULT = expr;
473         :}     
474         
475         | LITERAL OPENPAREN literal:literal CLOSEPAREN
476         {:
477         debugMessage(PRODSTRING);
478         ParseNode expr = new ParseNode("expr", parser.curLine(4));
479         expr.addChild(literal);
480         RESULT = expr;
481         :}
482         
483         | expr:expr DOT ID:relname
484         {:
485         debugMessage(PRODSTRING);
486         ParseNode relation = (new ParseNode("expr", parser.curLine(3))).addChild("relation");
487         relation.addChild(expr);
488         relation.addChild("name").addChild(relname);
489         RESULT = relation.getRoot();
490         :}
491         
492         | expr:expr DOTINV ID:relname
493         {:
494         debugMessage(PRODSTRING);
495         ParseNode relation = (new ParseNode("expr", parser.curLine(3))).addChild("relation");
496         relation.addChild(expr);
497         relation.addChild("name").addChild(relname);
498         relation.addChild("inv");
499         RESULT = relation.getRoot();
500         :}
501              
502         | expr:expr1 operator:operator expr:expr2
503         {:
504         debugMessage(PRODSTRING);
505         ParseNode op = (new ParseNode("expr", parser.curLine(3))).addChild("operator");
506         op.addChild("op").addChild(operator);
507         op.addChild("left", parser.curLine(3)).addChild(expr1);
508         op.addChild("right", parser.curLine(1)).addChild(expr2);
509         RESULT = op.getRoot();
510         :}
511
512         | SIZEOF OPENPAREN setexpr:setexpr CLOSEPAREN
513         {:
514         ParseNode sizeof = (new ParseNode("expr", parser.curLine(4))).addChild("sizeof");
515         sizeof.addChild(setexpr);
516         RESULT = sizeof.getRoot();
517         :}
518         ;
519
520 operator ::=
521           
522         ADD 
523         {:
524         debugMessage(PRODSTRING);
525         RESULT = new ParseNode("add", parser.curLine(1));
526         :}
527           
528         | SUB
529         {:
530         debugMessage(PRODSTRING);
531         RESULT = new ParseNode("sub", parser.curLine(1));
532         :}
533           
534         | MULT
535         {:
536         debugMessage(PRODSTRING);
537         RESULT = new ParseNode("mult", parser.curLine(1));
538         :}
539           
540         | DIV
541         {:
542         debugMessage(PRODSTRING);
543         RESULT = new ParseNode("div", parser.curLine(1));
544         :}
545         ;
546
547 compare ::= 
548
549         LT
550         {:
551         debugMessage(PRODSTRING);
552         RESULT = new ParseNode("lt", parser.curLine(1));
553         :}
554
555         | GT
556         {:
557         debugMessage(PRODSTRING);
558         RESULT = new ParseNode("gt", parser.curLine(1));
559         :}
560
561         | LE
562         {:
563         debugMessage(PRODSTRING);
564         RESULT = new ParseNode("le", parser.curLine(1));
565         :}
566
567         | GE
568         {:
569         debugMessage(PRODSTRING);
570         RESULT = new ParseNode("ge", parser.curLine(1));
571         :}
572
573         | EQ
574         {:
575         debugMessage(PRODSTRING);
576         RESULT = new ParseNode("eq", parser.curLine(1));
577         :}
578
579         | NE
580         {:
581         debugMessage(PRODSTRING);
582         RESULT = new ParseNode("ne", parser.curLine(1));
583         :}
584         ;
585         
586 literal ::=
587          
588         TRUE
589         {:
590         debugMessage(PRODSTRING);
591         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("boolean").addChild("true").getRoot();
592         :}
593          
594         | FALSE
595         {:
596         debugMessage(PRODSTRING);
597         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("boolean").addChild("false").getRoot();
598         :}
599          
600         | DECIMAL:dec
601         {:
602         debugMessage(PRODSTRING);
603         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("decimal").addChild(dec).getRoot();
604         :}
605          
606         | STRING:str
607         {:
608         debugMessage(PRODSTRING);
609         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("string").addChild(str).getRoot();
610         :}
611          
612         | CHAR:chr
613         {:
614         debugMessage(PRODSTRING);
615         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("char").addChild(chr).getRoot();
616         :}
617          
618         | ID:literal
619         {:
620         debugMessage(PRODSTRING);
621         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("token").addChild(literal).getRoot();
622         :}
623         ;