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