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