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