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