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