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