correct
[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     terminal SUM;
136
137     terminal NOT;
138     terminal LT;
139     terminal GT;
140     terminal LE;
141     terminal GE;
142     terminal EQ;
143     terminal NE;
144
145     terminal FORALL;
146     terminal IN;
147     terminal INTEST;
148     terminal THIS;
149
150     terminal COMMA;
151     terminal SIZEOF;
152
153     terminal DOT;
154     terminal DOTINV;
155
156     terminal AND;
157     terminal OR;
158
159     terminal LITERAL;
160
161     terminal IMPLIES;
162     terminal TRUE;
163     terminal FALSE;
164     terminal ISVALID;
165     terminal FOR;
166     terminal TO;
167     terminal CAST;
168
169     terminal PARAM;
170     terminal STRUCTURE;
171     terminal RESERVED;
172     terminal BIT;
173     terminal BYTE;
174     terminal SHORT;
175       
176     terminal LABEL;
177     terminal INT;
178     terminal SUBTYPE;
179     terminal SUBCLASS;
180     terminal OF;
181
182     terminal SEMICOLON;
183     terminal COLON;
184
185     terminal SET;
186     terminal ARROW;
187     terminal MANY;
188     terminal BAR;
189
190     terminal PARTITION;
191     terminal ELEMENT;
192     terminal DELAY;
193     terminal STATIC;
194
195     terminal NULL;
196     terminal CRASH;
197
198 // NON-TERMINALS /////////////////////////////////////////////////////////
199
200 /*
201                 TYPE                    NAME
202 ------------------------------------------------------------------------*/
203 nonterminal     ParseNode               constraints;
204 nonterminal     ParseNode               constraint;
205 nonterminal     ParseNode               optcrash;
206 nonterminal     ParseNode               quantifiers;
207 nonterminal     ParseNode               quantifier;
208 nonterminal     ParseNode               set;
209 nonterminal     ParseNode               listofliterals;
210 nonterminal     ParseNode               literal;
211 nonterminal     ParseNode               body;
212 nonterminal     ParseNode               predicate;
213 nonterminal     ParseNode               setexpr;
214
215 nonterminal     ParseNode               compare;
216 nonterminal     ParseNode               expr;
217 nonterminal     ParseNode               addsuboperator;
218 nonterminal     ParseNode               multdivoperator;
219
220
221
222 precedence left OR;
223 precedence left AND;
224 precedence left EQ, NE; 
225 precedence left LT, LE, GE, GT;
226
227 precedence left ADD, SUB;
228 precedence left MULT, DIV;
229
230 precedence left NOT;
231
232 precedence left DOT, DOTINV;
233
234 // PRODUCTION RULES  /////////////////////////////////////////////////////
235
236 constraints ::=
237             
238         constraints:constraints constraint:constraint
239         {:
240         debugMessage(PRODSTRING);
241         constraints.addChild(constraint);
242         RESULT = constraints;
243         :}
244         
245         | constraint:constraint
246         {:
247         debugMessage(PRODSTRING);
248         ParseNode constraints = new ParseNode("constraints", parser.curLine(1));
249         constraints.addChild(constraint);
250         RESULT = constraints;
251         :}
252         ;
253
254 constraint ::=
255             
256         optcrash:crash OPENBRACKET quantifiers:quantifiers CLOSEBRACKET COMMA body:body SEMICOLON
257         {:
258         debugMessage(PRODSTRING);
259         ParseNode constraint = new ParseNode("constraint", parser.curLine(7));
260         if (crash != null) {
261                 constraint.addChild(crash);
262         }
263         if (quantifiers != null) {
264                 constraint.addChild(quantifiers);
265         }
266         constraint.addChild(body);
267         RESULT = constraint;
268         :}
269         ;
270
271 optcrash ::=
272
273          CRASH
274          {:
275          debugMessage(PRODSTRING);
276          RESULT = new ParseNode("crash", parser.curLine(1));
277          :}
278
279          | /* nothing */
280          {:
281          debugMessage(PRODSTRING);
282          RESULT = null;
283          :}
284          ;
285
286 quantifiers ::=
287             
288         quantifiers:quantifiers COMMA quantifier:quantifier
289         {:
290         debugMessage(PRODSTRING);
291         quantifiers.addChild(quantifier);
292         RESULT = quantifiers;
293         :}
294             
295         | quantifier:quantifier
296         {:
297         debugMessage(PRODSTRING);
298         ParseNode quantifiers = new ParseNode("quantifiers", parser.curLine(1));
299         quantifiers.addChild(quantifier);
300         RESULT = quantifiers;
301         :}
302             
303         | 
304         {:
305         debugMessage(PRODSTRING);
306         RESULT = null;
307         :}
308         ;       
309
310 quantifier ::= 
311            
312         FORALL ID:var IN set:set
313         {:
314         debugMessage(PRODSTRING);
315         ParseNode q = new ParseNode("quantifier", parser.curLine(4));
316         q.addChild("forall", parser.curLine(4));
317         q.addChild("var", parser.curLine(3)).addChild(var);
318         q.addChild(set);
319         RESULT = q;
320         :}
321         | FORALL LT ID:r1 COMMA ID:r2 GT IN ID:relation
322         {:
323         debugMessage(PRODSTRING);
324         ParseNode q = new ParseNode("quantifier", parser.curLine(7));
325         q.addChild("relation", parser.curLine(1)).addChild(relation);
326         q.addChild("left", parser.curLine(5)).addChild(r1);
327         q.addChild("right", parser.curLine(3)).addChild(r2);
328         RESULT = q;
329         :}
330         ;
331
332 set ::=
333     
334         ID:setname
335         {:
336         debugMessage(PRODSTRING);
337         ParseNode set = new ParseNode("set", parser.curLine(1));
338         set.addChild("name").addChild(setname);
339         RESULT = set;
340         :}
341
342         | OPENBRACE listofliterals:list CLOSEBRACE
343         {:
344         debugMessage(PRODSTRING);
345         ParseNode set = new ParseNode("set", parser.curLine(3));
346         set.addChild(list);
347         RESULT = set;
348         :}
349         ;
350     
351 listofliterals ::=
352                
353         listofliterals:list COMMA literal:literal
354         {:
355         debugMessage(PRODSTRING);
356         list.addChild(literal);
357         RESULT = list;
358         :}
359                
360         | literal:literal
361         {: 
362         debugMessage(PRODSTRING);
363         ParseNode list = new ParseNode("listofliterals", parser.curLine(1));
364         list.addChild(literal);
365         RESULT = list;
366         :}
367         ;
368
369 body ::=
370
371         body:body1 AND body:body2
372         {:
373         debugMessage(PRODSTRING);
374         ParseNode body = new ParseNode("body", parser.curLine(3));
375         body.addChild("and").addChild("left", parser.curLine(3)).addChild(body1);
376         body.getChild("and").addChild("right", parser.curLine(1)).addChild(body2);
377         RESULT = body;
378         :}
379      
380         | body:body1 OR body:body2
381         {:
382         debugMessage(PRODSTRING);
383         ParseNode body = new ParseNode("body", parser.curLine(3));
384         body.addChild("or").addChild("left", parser.curLine(3)).addChild(body1);
385         body.getChild("or").addChild("right", parser.curLine(1)).addChild(body2);
386         RESULT = body;
387         :}
388      
389         | NOT body:body1
390         {:
391         debugMessage(PRODSTRING);
392         ParseNode body = new ParseNode("body", parser.curLine(2));
393         body.addChild("not").addChild(body1);
394         RESULT = body;
395         :}
396      
397         | OPENPAREN body:body CLOSEPAREN
398         {:
399         debugMessage(PRODSTRING);
400         RESULT = body;
401         :}
402      
403         | predicate:predicate
404         {:
405         debugMessage(PRODSTRING);
406         ParseNode body = new ParseNode("body", parser.curLine(1));
407         body.addChild(predicate);
408         RESULT = body;
409         :}
410         ;
411
412 predicate ::=
413
414         expr:expr IN setexpr:setexpr
415         {:
416         debugMessage(PRODSTRING);
417         ParseNode inclusion = (new ParseNode("predicate", parser.curLine(3))).addChild("inclusion");
418         inclusion.addChild(expr);
419         inclusion.addChild(setexpr);
420         RESULT = inclusion.getRoot();
421         :}
422      
423         | expr:lexpr compare:compare expr:rexpr
424         {:
425         debugMessage(PRODSTRING);
426         ParseNode comparison = (new ParseNode("predicate", parser.curLine(3))).addChild("expr").addChild("operator");
427         comparison.addChild("op").addChild(compare);
428         comparison.addChild("left", parser.curLine(2)).addChild(lexpr);
429         comparison.addChild("right", parser.curLine(2)).addChild(rexpr);
430         RESULT = comparison.getRoot();
431         :}
432
433         ;
434
435 setexpr ::=
436         
437         ID:setname
438         {:
439         debugMessage(PRODSTRING);
440         ParseNode set = new ParseNode("setexpr", parser.curLine(1));
441         set.addChild("set").addChild(setname);
442         RESULT = set;
443         :}
444
445         | ID:var DOT ID:relation
446         {:
447         debugMessage(PRODSTRING);
448         ParseNode set = new ParseNode("setexpr", parser.curLine(3));
449         set.addChild("dot").addChild("quantifiervar", parser.curLine(3)).addChild(var);
450         set.getChild("dot").addChild("relation", parser.curLine(1)).addChild(relation);
451         RESULT = set;
452         :}
453
454         | ID:var DOTINV ID:relation
455         {:
456         debugMessage(PRODSTRING);
457         ParseNode set = new ParseNode("setexpr", parser.curLine(3));
458         set.addChild("dotinv").addChild("quantifiervar", parser.curLine(3)).addChild(var);
459         set.getChild("dotinv").addChild("relation", parser.curLine(1)).addChild(relation);
460         RESULT = set;
461         :}
462
463         | setexpr:setexpr DOT ID:relation
464         {:
465         debugMessage(PRODSTRING);
466         ParseNode set = new ParseNode("setexpr", parser.curLine(3));
467         set.addChild("dotset").addChild(setexpr);
468         set.getChild("dotset").addChild("relation", parser.curLine(1)).addChild(relation);
469         RESULT = set;
470         :}
471
472         | setexpr:setexpr DOTINV ID:relation
473         {:
474         debugMessage(PRODSTRING);
475         ParseNode set = new ParseNode("setexpr", parser.curLine(3));
476         set.addChild("dotinvset").addChild(setexpr);
477         set.getChild("dotinvset").addChild("relation", parser.curLine(1)).addChild(relation);
478         RESULT = set;
479         :}
480         ;
481         
482 expr ::=
483
484         SUM OPENPAREN ID:set DOT ID:relation CLOSEPAREN
485         {:
486         debugMessage(PRODSTRING);
487         ParseNode expr = new ParseNode("expr", parser.curLine(1));      
488         expr.addChild("sumexpr", parser.curLine(3));
489         expr.getChild("sumexpr").addChild("dot").addChild("set", parser.curLine(3)).addChild(set);
490         expr.getChild("sumexpr").getChild("dot").addChild("relation", parser.curLine(1)).addChild(relation);
491         RESULT = expr;
492         :}
493
494         | ID:var
495         {:
496         debugMessage(PRODSTRING);
497         ParseNode expr = new ParseNode("expr", parser.curLine(1));      
498         expr.addChild("var").addChild(var);
499         RESULT = expr;
500         :}
501         
502         | OPENPAREN expr:expr CLOSEPAREN 
503         {:
504         debugMessage(PRODSTRING);
505         RESULT = expr;
506         :}     
507         
508         | literal:literal
509         {:
510         debugMessage(PRODSTRING);
511         ParseNode expr = new ParseNode("expr", parser.curLine(4));
512         expr.addChild(literal);
513         RESULT = expr;
514         :}
515         
516         | expr:expr DOT ID:relname
517         {:
518         debugMessage(PRODSTRING);
519         ParseNode relation = (new ParseNode("expr", parser.curLine(3))).addChild("relation");
520         relation.addChild(expr);
521         relation.addChild("name").addChild(relname);
522         RESULT = relation.getRoot();
523         :}
524         
525         | expr:expr DOTINV ID:relname
526         {:
527         debugMessage(PRODSTRING);
528         ParseNode relation = (new ParseNode("expr", parser.curLine(3))).addChild("relation");
529         relation.addChild(expr);
530         relation.addChild("name").addChild(relname);
531         relation.addChild("inv");
532         RESULT = relation.getRoot();
533         :}
534              
535         | expr:expr1 addsuboperator:operator expr:expr2
536         {:
537         debugMessage(PRODSTRING);
538         ParseNode op = (new ParseNode("expr", parser.curLine(3))).addChild("operator");
539         op.addChild("op").addChild(operator);
540         op.addChild("left", parser.curLine(3)).addChild(expr1);
541         op.addChild("right", parser.curLine(1)).addChild(expr2);
542         RESULT = op.getRoot();
543         :}
544         %prec ADD
545         | expr:expr1 multdivoperator:operator expr:expr2
546         {:
547         debugMessage(PRODSTRING);
548         ParseNode op = (new ParseNode("expr", parser.curLine(3))).addChild("operator");
549         op.addChild("op").addChild(operator);
550         op.addChild("left", parser.curLine(3)).addChild(expr1);
551         op.addChild("right", parser.curLine(1)).addChild(expr2);
552         RESULT = op.getRoot();
553         :}
554         %prec MULT
555         | SIZEOF OPENPAREN setexpr:setexpr CLOSEPAREN
556         {:
557         ParseNode sizeof = (new ParseNode("expr", parser.curLine(4))).addChild("sizeof");
558         sizeof.addChild(setexpr);
559         RESULT = sizeof.getRoot();
560         :}
561         ;
562
563 addsuboperator ::=
564           
565         ADD 
566         {:
567         debugMessage(PRODSTRING);
568         RESULT = new ParseNode("add", parser.curLine(1));
569         :}
570           
571         | SUB
572         {:
573         debugMessage(PRODSTRING);
574         RESULT = new ParseNode("sub", parser.curLine(1));
575         :}
576         ;
577 multdivoperator ::=
578         MULT
579         {:
580         debugMessage(PRODSTRING);
581         RESULT = new ParseNode("mult", parser.curLine(1));
582         :}
583         | DIV
584         {:
585         debugMessage(PRODSTRING);
586         RESULT = new ParseNode("div", parser.curLine(1));
587         :}
588         ;
589
590 compare ::= 
591
592         LT
593         {:
594         debugMessage(PRODSTRING);
595         RESULT = new ParseNode("lt", parser.curLine(1));
596         :}
597
598         | GT
599         {:
600         debugMessage(PRODSTRING);
601         RESULT = new ParseNode("gt", parser.curLine(1));
602         :}
603
604         | LE
605         {:
606         debugMessage(PRODSTRING);
607         RESULT = new ParseNode("le", parser.curLine(1));
608         :}
609
610         | GE
611         {:
612         debugMessage(PRODSTRING);
613         RESULT = new ParseNode("ge", parser.curLine(1));
614         :}
615
616         | EQ
617         {:
618         debugMessage(PRODSTRING);
619         RESULT = new ParseNode("eq", parser.curLine(1));
620         :}
621
622         | NE
623         {:
624         debugMessage(PRODSTRING);
625         RESULT = new ParseNode("ne", parser.curLine(1));
626         :}
627         ;
628         
629 literal ::=
630          
631         TRUE
632         {:
633         debugMessage(PRODSTRING);
634         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("boolean").addChild("true").getRoot();
635         :}
636          
637         | FALSE
638         {:
639         debugMessage(PRODSTRING);
640         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("boolean").addChild("false").getRoot();
641         :}
642
643         | NULL
644         {:
645         debugMessage(PRODSTRING);
646         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("decimal").addChild("0").getRoot();
647         :}
648          
649         | DECIMAL:dec
650         {:
651         debugMessage(PRODSTRING);
652         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("decimal").addChild(dec).getRoot();
653         :}
654
655         | SUB DECIMAL:dec
656         {:
657         debugMessage(PRODSTRING);
658         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("decimal").addChild("-"+dec).getRoot();
659         :}
660          
661         | STRING:str
662         {:
663         debugMessage(PRODSTRING);
664         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("string").addChild(str).getRoot();
665         :}
666          
667         | CHAR:chr
668         {:
669         debugMessage(PRODSTRING);
670         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("char").addChild(chr).getRoot();
671         :}
672          
673         | LITERAL OPENPAREN ID:literal CLOSEPAREN
674         {:
675         debugMessage(PRODSTRING);
676         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("token").addChild(literal).getRoot();
677         :}
678         ;