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