model and checks
[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 right EQ, NE; 
206 precedence right LT, LE, GE, GT;
207 precedence left ADD, SUB;
208 precedence left MULT, DIV;
209 precedence left NOT;
210 precedence left DOT, DOTINV;
211
212 // PRODUCTION RULES  /////////////////////////////////////////////////////
213
214 constraints ::=
215             
216         constraints:constraints constraint:constraint
217         {:
218         debugMessage(PRODSTRING);
219         constraints.addChild(constraint);
220         RESULT = constraints;
221         :}
222         
223         | constraint:constraint
224         {:
225         debugMessage(PRODSTRING);
226         ParseNode constraints = new ParseNode("constraints", parser.curLine(1));
227         constraints.addChild(constraint);
228         RESULT = constraints;
229         :}
230         ;
231
232 constraint ::=
233             
234         optcrash:crash OPENBRACKET quantifiers:quantifiers CLOSEBRACKET COMMA body:body SEMICOLON
235         {:
236         debugMessage(PRODSTRING);
237         ParseNode constraint = new ParseNode("constraint", parser.curLine(7));
238         if (crash != null) {
239                 constraint.addChild(crash);
240         }
241         if (quantifiers != null) {
242                 constraint.addChild(quantifiers);
243         }
244         constraint.addChild(body);
245         RESULT = constraint;
246         :}
247         ;
248
249 optcrash ::=
250
251          CRASH
252          {:
253          debugMessage(PRODSTRING);
254          RESULT = new ParseNode("crash", parser.curLine(1));
255          :}
256
257          | /* nothing */
258          {:
259          debugMessage(PRODSTRING);
260          RESULT = null;
261          :}
262          ;
263
264 quantifiers ::=
265             
266         quantifiers:quantifiers COMMA quantifier:quantifier
267         {:
268         debugMessage(PRODSTRING);
269         quantifiers.addChild(quantifier);
270         RESULT = quantifiers;
271         :}
272             
273         | quantifier:quantifier
274         {:
275         debugMessage(PRODSTRING);
276         ParseNode quantifiers = new ParseNode("quantifiers", parser.curLine(1));
277         quantifiers.addChild(quantifier);
278         RESULT = quantifiers;
279         :}
280             
281         | 
282         {:
283         debugMessage(PRODSTRING);
284         RESULT = null;
285         :}
286         ;       
287
288 quantifier ::= 
289            
290         FORALL ID:var IN set:set
291         {:
292         debugMessage(PRODSTRING);
293         ParseNode q = new ParseNode("quantifier", parser.curLine(4));
294         q.addChild("forall", parser.curLine(4));
295         q.addChild("var", parser.curLine(3)).addChild(var);
296         q.addChild(set);
297         RESULT = q;
298         :}
299         ;
300
301 set ::=
302     
303         ID:setname
304         {:
305         debugMessage(PRODSTRING);
306         ParseNode set = new ParseNode("set", parser.curLine(1));
307         set.addChild("name").addChild(setname);
308         RESULT = set;
309         :}
310
311         | OPENBRACE listofliterals:list CLOSEBRACE
312         {:
313         debugMessage(PRODSTRING);
314         ParseNode set = new ParseNode("set", parser.curLine(3));
315         set.addChild(list);
316         RESULT = set;
317         :}
318         ;
319     
320 listofliterals ::=
321                
322         listofliterals:list COMMA literal:literal
323         {:
324         debugMessage(PRODSTRING);
325         list.addChild(literal);
326         RESULT = list;
327         :}
328                
329         | literal:literal
330         {: 
331         debugMessage(PRODSTRING);
332         ParseNode list = new ParseNode("listofliterals", parser.curLine(1));
333         list.addChild(literal);
334         RESULT = list;
335         :}
336         ;
337
338 body ::=
339
340         body:body1 AND body:body2
341         {:
342         debugMessage(PRODSTRING);
343         ParseNode body = new ParseNode("body", parser.curLine(3));
344         body.addChild("and").addChild("left", parser.curLine(3)).addChild(body1);
345         body.getChild("and").addChild("right", parser.curLine(1)).addChild(body2);
346         RESULT = body;
347         :}
348      
349         | body:body1 OR body:body2
350         {:
351         debugMessage(PRODSTRING);
352         ParseNode body = new ParseNode("body", parser.curLine(3));
353         body.addChild("or").addChild("left", parser.curLine(3)).addChild(body1);
354         body.getChild("or").addChild("right", parser.curLine(1)).addChild(body2);
355         RESULT = body;
356         :}
357      
358         | NOT body:body1
359         {:
360         debugMessage(PRODSTRING);
361         ParseNode body = new ParseNode("body", parser.curLine(2));
362         body.addChild("not").addChild(body1);
363         RESULT = body;
364         :}
365      
366         | OPENPAREN body:body CLOSEPAREN
367         {:
368         debugMessage(PRODSTRING);
369         RESULT = body;
370         :}
371      
372         | predicate:predicate
373         {:
374         debugMessage(PRODSTRING);
375         ParseNode body = new ParseNode("body", parser.curLine(1));
376         body.addChild(predicate);
377         RESULT = body;
378         :}
379         ;
380
381 predicate ::=
382
383         ID:var IN setexpr:setexpr
384         {:
385         debugMessage(PRODSTRING);
386         ParseNode inclusion = (new ParseNode("predicate", parser.curLine(3))).addChild("inclusion");
387         inclusion.addChild("quantifiervar", parser.curLine(3)).addChild(var);
388         inclusion.addChild(setexpr);
389         RESULT = inclusion.getRoot();
390         :}
391      
392         | SIZEOF OPENPAREN setexpr:setexpr CLOSEPAREN compare:compare LITERAL OPENPAREN DECIMAL:dec CLOSEPAREN
393         {:
394         ParseNode sizeof = (new ParseNode("predicate", parser.curLine(4))).addChild("sizeof");
395         sizeof.addChild(setexpr);
396         sizeof.addChild("compare", parser.curLine(2)).addChild(compare);
397         sizeof.addChild("decimal", parser.curLine(1)).addChild(dec);
398         RESULT = sizeof.getRoot();
399         :}
400
401         | ID:var DOT ID:relation compare:compare expr:expr
402         {:
403         debugMessage(PRODSTRING);
404         ParseNode comparison = (new ParseNode("predicate", parser.curLine(3))).addChild("comparison");
405         comparison.addChild("compare", parser.curLine(2)).addChild(compare);
406         comparison.addChild("relation", parser.curLine(3)).addChild(relation);
407         comparison.addChild("quantifier", parser.curLine(5)).addChild(var);
408         comparison.addChild(expr);
409         RESULT = comparison.getRoot();
410         :}
411         ;
412
413 setexpr ::=
414         
415         ID:setname
416         {:
417         debugMessage(PRODSTRING);
418         ParseNode set = new ParseNode("setexpr", parser.curLine(1));
419         set.addChild("set").addChild(setname);
420         RESULT = set;
421         :}
422
423         | ID:var DOT ID:relation
424         {:
425         debugMessage(PRODSTRING);
426         ParseNode set = new ParseNode("setexpr", parser.curLine(3));
427         set.addChild("dot").addChild("quantifiervar", parser.curLine(3)).addChild(var);
428         set.getChild("dot").addChild("relation", parser.curLine(1)).addChild(relation);
429         RESULT = set;
430         :}
431
432         | ID:var DOTINV ID:relation
433         {:
434         debugMessage(PRODSTRING);
435         ParseNode set = new ParseNode("setexpr", parser.curLine(3));
436         set.addChild("dotinv").addChild("quantifiervar", parser.curLine(3)).addChild(var);
437         set.getChild("dotinv").addChild("relation", parser.curLine(1)).addChild(relation);
438         RESULT = set;
439         :}
440         ;
441         
442 expr ::=
443         
444         ID:var
445         {:
446         debugMessage(PRODSTRING);
447         ParseNode expr = new ParseNode("expr", parser.curLine(1));      
448         expr.addChild("var").addChild(var);
449         RESULT = expr;
450         :}
451         
452         | OPENPAREN expr:expr CLOSEPAREN 
453         {:
454         debugMessage(PRODSTRING);
455         RESULT = expr;
456         :}     
457         
458         | LITERAL OPENPAREN literal:literal CLOSEPAREN
459         {:
460         debugMessage(PRODSTRING);
461         ParseNode expr = new ParseNode("expr", parser.curLine(4));
462         expr.addChild(literal);
463         RESULT = expr;
464         :}
465         
466         | expr:expr DOT ID:relname
467         {:
468         debugMessage(PRODSTRING);
469         ParseNode relation = (new ParseNode("expr", parser.curLine(3))).addChild("relation");
470         relation.addChild(expr);
471         relation.addChild("name").addChild(relname);
472         RESULT = relation.getRoot();
473         :}
474         
475         | expr:expr DOTINV ID:relname
476         {:
477         debugMessage(PRODSTRING);
478         ParseNode relation = (new ParseNode("expr", parser.curLine(3))).addChild("relation");
479         relation.addChild(expr);
480         relation.addChild("name").addChild(relname);
481         relation.addChild("inv");
482         RESULT = relation.getRoot();
483         :}
484              
485         | expr:expr1 operator:operator expr:expr2
486         {:
487         debugMessage(PRODSTRING);
488         ParseNode op = (new ParseNode("expr", parser.curLine(3))).addChild("operator");
489         op.addChild("op").addChild(operator);
490         op.addChild("left", parser.curLine(3)).addChild(expr1);
491         op.addChild("right", parser.curLine(1)).addChild(expr2);
492         RESULT = op.getRoot();
493         :}
494
495         | SIZEOF OPENPAREN setexpr:setexpr CLOSEPAREN
496         {:
497         ParseNode sizeof = (new ParseNode("expr", parser.curLine(4))).addChild("sizeof");
498         sizeof.addChild(setexpr);
499         RESULT = sizeof.getRoot();
500         :}
501         ;
502
503 operator ::=
504           
505         ADD 
506         {:
507         debugMessage(PRODSTRING);
508         RESULT = new ParseNode("add", parser.curLine(1));
509         :}
510           
511         | SUB
512         {:
513         debugMessage(PRODSTRING);
514         RESULT = new ParseNode("sub", parser.curLine(1));
515         :}
516           
517         | MULT
518         {:
519         debugMessage(PRODSTRING);
520         RESULT = new ParseNode("mult", parser.curLine(1));
521         :}
522           
523         | DIV
524         {:
525         debugMessage(PRODSTRING);
526         RESULT = new ParseNode("div", parser.curLine(1));
527         :}
528         ;
529
530 compare ::= 
531
532         LT
533         {:
534         debugMessage(PRODSTRING);
535         RESULT = new ParseNode("lt", parser.curLine(1));
536         :}
537
538         | GT
539         {:
540         debugMessage(PRODSTRING);
541         RESULT = new ParseNode("gt", parser.curLine(1));
542         :}
543
544         | LE
545         {:
546         debugMessage(PRODSTRING);
547         RESULT = new ParseNode("le", parser.curLine(1));
548         :}
549
550         | GE
551         {:
552         debugMessage(PRODSTRING);
553         RESULT = new ParseNode("ge", parser.curLine(1));
554         :}
555
556         | EQ
557         {:
558         debugMessage(PRODSTRING);
559         RESULT = new ParseNode("eq", parser.curLine(1));
560         :}
561
562         | NE
563         {:
564         debugMessage(PRODSTRING);
565         RESULT = new ParseNode("ne", parser.curLine(1));
566         :}
567         ;
568         
569 literal ::=
570          
571         TRUE
572         {:
573         debugMessage(PRODSTRING);
574         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("boolean").addChild("true").getRoot();
575         :}
576          
577         | FALSE
578         {:
579         debugMessage(PRODSTRING);
580         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("boolean").addChild("false").getRoot();
581         :}
582          
583         | DECIMAL:dec
584         {:
585         debugMessage(PRODSTRING);
586         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("decimal").addChild(dec).getRoot();
587         :}
588          
589         | STRING:str
590         {:
591         debugMessage(PRODSTRING);
592         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("string").addChild(str).getRoot();
593         :}
594          
595         | CHAR:chr
596         {:
597         debugMessage(PRODSTRING);
598         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("char").addChild(chr).getRoot();
599         :}
600          
601         | ID:literal
602         {:
603         debugMessage(PRODSTRING);
604         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("token").addChild(literal).getRoot();
605         :}
606         ;