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