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