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