test
[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         ;
303
304 set ::=
305     
306         ID:setname
307         {:
308         debugMessage(PRODSTRING);
309         ParseNode set = new ParseNode("set", parser.curLine(1));
310         set.addChild("name").addChild(setname);
311         RESULT = set;
312         :}
313
314         | OPENBRACE listofliterals:list CLOSEBRACE
315         {:
316         debugMessage(PRODSTRING);
317         ParseNode set = new ParseNode("set", parser.curLine(3));
318         set.addChild(list);
319         RESULT = set;
320         :}
321         ;
322     
323 listofliterals ::=
324                
325         listofliterals:list COMMA literal:literal
326         {:
327         debugMessage(PRODSTRING);
328         list.addChild(literal);
329         RESULT = list;
330         :}
331                
332         | literal:literal
333         {: 
334         debugMessage(PRODSTRING);
335         ParseNode list = new ParseNode("listofliterals", parser.curLine(1));
336         list.addChild(literal);
337         RESULT = list;
338         :}
339         ;
340
341 body ::=
342
343         body:body1 AND body:body2
344         {:
345         debugMessage(PRODSTRING);
346         ParseNode body = new ParseNode("body", parser.curLine(3));
347         body.addChild("and").addChild("left", parser.curLine(3)).addChild(body1);
348         body.getChild("and").addChild("right", parser.curLine(1)).addChild(body2);
349         RESULT = body;
350         :}
351      
352         | body:body1 OR body:body2
353         {:
354         debugMessage(PRODSTRING);
355         ParseNode body = new ParseNode("body", parser.curLine(3));
356         body.addChild("or").addChild("left", parser.curLine(3)).addChild(body1);
357         body.getChild("or").addChild("right", parser.curLine(1)).addChild(body2);
358         RESULT = body;
359         :}
360      
361         | NOT body:body1
362         {:
363         debugMessage(PRODSTRING);
364         ParseNode body = new ParseNode("body", parser.curLine(2));
365         body.addChild("not").addChild(body1);
366         RESULT = body;
367         :}
368      
369         | OPENPAREN body:body CLOSEPAREN
370         {:
371         debugMessage(PRODSTRING);
372         RESULT = body;
373         :}
374      
375         | predicate:predicate
376         {:
377         debugMessage(PRODSTRING);
378         ParseNode body = new ParseNode("body", parser.curLine(1));
379         body.addChild(predicate);
380         RESULT = body;
381         :}
382         ;
383
384 predicate ::=
385
386         expr:expr IN setexpr:setexpr
387         {:
388         debugMessage(PRODSTRING);
389         ParseNode inclusion = (new ParseNode("predicate", parser.curLine(3))).addChild("inclusion");
390         inclusion.addChild(expr);
391         inclusion.addChild(setexpr);
392         RESULT = inclusion.getRoot();
393         :}
394      
395         | expr:lexpr compare:compare expr:rexpr
396         {:
397         debugMessage(PRODSTRING);
398         ParseNode comparison = (new ParseNode("predicate", parser.curLine(3))).addChild("expr").addChild("operator");
399         comparison.addChild("op").addChild(compare);
400         comparison.addChild("left", parser.curLine(2)).addChild(lexpr);
401         comparison.addChild("right", parser.curLine(2)).addChild(rexpr);
402         RESULT = comparison.getRoot();
403         :}
404
405         ;
406
407 setexpr ::=
408         
409         ID:setname
410         {:
411         debugMessage(PRODSTRING);
412         ParseNode set = new ParseNode("setexpr", parser.curLine(1));
413         set.addChild("set").addChild(setname);
414         RESULT = set;
415         :}
416
417         | ID:var DOT ID:relation
418         {:
419         debugMessage(PRODSTRING);
420         ParseNode set = new ParseNode("setexpr", parser.curLine(3));
421         set.addChild("dot").addChild("quantifiervar", parser.curLine(3)).addChild(var);
422         set.getChild("dot").addChild("relation", parser.curLine(1)).addChild(relation);
423         RESULT = set;
424         :}
425
426         | ID:var DOTINV ID:relation
427         {:
428         debugMessage(PRODSTRING);
429         ParseNode set = new ParseNode("setexpr", parser.curLine(3));
430         set.addChild("dotinv").addChild("quantifiervar", parser.curLine(3)).addChild(var);
431         set.getChild("dotinv").addChild("relation", parser.curLine(1)).addChild(relation);
432         RESULT = set;
433         :}
434         ;
435         
436 expr ::=
437         
438         ID:var
439         {:
440         debugMessage(PRODSTRING);
441         ParseNode expr = new ParseNode("expr", parser.curLine(1));      
442         expr.addChild("var").addChild(var);
443         RESULT = expr;
444         :}
445         
446         | OPENPAREN expr:expr CLOSEPAREN 
447         {:
448         debugMessage(PRODSTRING);
449         RESULT = expr;
450         :}     
451         
452         | LITERAL OPENPAREN literal:literal CLOSEPAREN
453         {:
454         debugMessage(PRODSTRING);
455         ParseNode expr = new ParseNode("expr", parser.curLine(4));
456         expr.addChild(literal);
457         RESULT = expr;
458         :}
459         
460         | expr:expr DOT ID:relname
461         {:
462         debugMessage(PRODSTRING);
463         ParseNode relation = (new ParseNode("expr", parser.curLine(3))).addChild("relation");
464         relation.addChild(expr);
465         relation.addChild("name").addChild(relname);
466         RESULT = relation.getRoot();
467         :}
468         
469         | expr:expr DOTINV 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         relation.addChild("inv");
476         RESULT = relation.getRoot();
477         :}
478              
479         | expr:expr1 operator:operator expr:expr2
480         {:
481         debugMessage(PRODSTRING);
482         ParseNode op = (new ParseNode("expr", parser.curLine(3))).addChild("operator");
483         op.addChild("op").addChild(operator);
484         op.addChild("left", parser.curLine(3)).addChild(expr1);
485         op.addChild("right", parser.curLine(1)).addChild(expr2);
486         RESULT = op.getRoot();
487         :}
488
489         | SIZEOF OPENPAREN setexpr:setexpr CLOSEPAREN
490         {:
491         ParseNode sizeof = (new ParseNode("expr", parser.curLine(4))).addChild("sizeof");
492         sizeof.addChild(setexpr);
493         RESULT = sizeof.getRoot();
494         :}
495         ;
496
497 operator ::=
498           
499         ADD 
500         {:
501         debugMessage(PRODSTRING);
502         RESULT = new ParseNode("add", parser.curLine(1));
503         :}
504           
505         | SUB
506         {:
507         debugMessage(PRODSTRING);
508         RESULT = new ParseNode("sub", parser.curLine(1));
509         :}
510           
511         | MULT
512         {:
513         debugMessage(PRODSTRING);
514         RESULT = new ParseNode("mult", parser.curLine(1));
515         :}
516           
517         | DIV
518         {:
519         debugMessage(PRODSTRING);
520         RESULT = new ParseNode("div", parser.curLine(1));
521         :}
522         ;
523
524 compare ::= 
525
526         LT
527         {:
528         debugMessage(PRODSTRING);
529         RESULT = new ParseNode("lt", parser.curLine(1));
530         :}
531
532         | GT
533         {:
534         debugMessage(PRODSTRING);
535         RESULT = new ParseNode("gt", parser.curLine(1));
536         :}
537
538         | LE
539         {:
540         debugMessage(PRODSTRING);
541         RESULT = new ParseNode("le", parser.curLine(1));
542         :}
543
544         | GE
545         {:
546         debugMessage(PRODSTRING);
547         RESULT = new ParseNode("ge", parser.curLine(1));
548         :}
549
550         | EQ
551         {:
552         debugMessage(PRODSTRING);
553         RESULT = new ParseNode("eq", parser.curLine(1));
554         :}
555
556         | NE
557         {:
558         debugMessage(PRODSTRING);
559         RESULT = new ParseNode("ne", parser.curLine(1));
560         :}
561         ;
562         
563 literal ::=
564          
565         TRUE
566         {:
567         debugMessage(PRODSTRING);
568         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("boolean").addChild("true").getRoot();
569         :}
570          
571         | FALSE
572         {:
573         debugMessage(PRODSTRING);
574         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("boolean").addChild("false").getRoot();
575         :}
576          
577         | DECIMAL:dec
578         {:
579         debugMessage(PRODSTRING);
580         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("decimal").addChild(dec).getRoot();
581         :}
582          
583         | STRING:str
584         {:
585         debugMessage(PRODSTRING);
586         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("string").addChild(str).getRoot();
587         :}
588          
589         | CHAR:chr
590         {:
591         debugMessage(PRODSTRING);
592         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("char").addChild(chr).getRoot();
593         :}
594          
595         | ID:literal
596         {:
597         debugMessage(PRODSTRING);
598         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("token").addChild(literal).getRoot();
599         :}
600         ;