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