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