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