2f7f2daa4f08e5da2e73de250d8fe7bd101e2ed5
[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         
462 expr ::=
463         
464         ID:var
465         {:
466         debugMessage(PRODSTRING);
467         ParseNode expr = new ParseNode("expr", parser.curLine(1));      
468         expr.addChild("var").addChild(var);
469         RESULT = expr;
470         :}
471         
472         | OPENPAREN expr:expr CLOSEPAREN 
473         {:
474         debugMessage(PRODSTRING);
475         RESULT = expr;
476         :}     
477         
478         | literal:literal
479         {:
480         debugMessage(PRODSTRING);
481         ParseNode expr = new ParseNode("expr", parser.curLine(4));
482         expr.addChild(literal);
483         RESULT = expr;
484         :}
485         
486         | expr:expr DOT ID:relname
487         {:
488         debugMessage(PRODSTRING);
489         ParseNode relation = (new ParseNode("expr", parser.curLine(3))).addChild("relation");
490         relation.addChild(expr);
491         relation.addChild("name").addChild(relname);
492         RESULT = relation.getRoot();
493         :}
494         
495         | expr:expr DOTINV ID:relname
496         {:
497         debugMessage(PRODSTRING);
498         ParseNode relation = (new ParseNode("expr", parser.curLine(3))).addChild("relation");
499         relation.addChild(expr);
500         relation.addChild("name").addChild(relname);
501         relation.addChild("inv");
502         RESULT = relation.getRoot();
503         :}
504              
505         | expr:expr1 operator:operator expr:expr2
506         {:
507         debugMessage(PRODSTRING);
508         ParseNode op = (new ParseNode("expr", parser.curLine(3))).addChild("operator");
509         op.addChild("op").addChild(operator);
510         op.addChild("left", parser.curLine(3)).addChild(expr1);
511         op.addChild("right", parser.curLine(1)).addChild(expr2);
512         RESULT = op.getRoot();
513         :}
514
515         | SIZEOF OPENPAREN setexpr:setexpr CLOSEPAREN
516         {:
517         ParseNode sizeof = (new ParseNode("expr", parser.curLine(4))).addChild("sizeof");
518         sizeof.addChild(setexpr);
519         RESULT = sizeof.getRoot();
520         :}
521         ;
522
523 operator ::=
524           
525         ADD 
526         {:
527         debugMessage(PRODSTRING);
528         RESULT = new ParseNode("add", parser.curLine(1));
529         :}
530           
531         | SUB
532         {:
533         debugMessage(PRODSTRING);
534         RESULT = new ParseNode("sub", parser.curLine(1));
535         :}
536           
537         | MULT
538         {:
539         debugMessage(PRODSTRING);
540         RESULT = new ParseNode("mult", parser.curLine(1));
541         :}
542           
543         | DIV
544         {:
545         debugMessage(PRODSTRING);
546         RESULT = new ParseNode("div", parser.curLine(1));
547         :}
548         ;
549
550 compare ::= 
551
552         LT
553         {:
554         debugMessage(PRODSTRING);
555         RESULT = new ParseNode("lt", parser.curLine(1));
556         :}
557
558         | GT
559         {:
560         debugMessage(PRODSTRING);
561         RESULT = new ParseNode("gt", parser.curLine(1));
562         :}
563
564         | LE
565         {:
566         debugMessage(PRODSTRING);
567         RESULT = new ParseNode("le", parser.curLine(1));
568         :}
569
570         | GE
571         {:
572         debugMessage(PRODSTRING);
573         RESULT = new ParseNode("ge", parser.curLine(1));
574         :}
575
576         | EQ
577         {:
578         debugMessage(PRODSTRING);
579         RESULT = new ParseNode("eq", parser.curLine(1));
580         :}
581
582         | NE
583         {:
584         debugMessage(PRODSTRING);
585         RESULT = new ParseNode("ne", parser.curLine(1));
586         :}
587         ;
588         
589 literal ::=
590          
591         TRUE
592         {:
593         debugMessage(PRODSTRING);
594         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("boolean").addChild("true").getRoot();
595         :}
596          
597         | FALSE
598         {:
599         debugMessage(PRODSTRING);
600         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("boolean").addChild("false").getRoot();
601         :}
602
603         | NULL
604         {:
605         debugMessage(PRODSTRING);
606         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("decimal").addChild("0").getRoot();
607         :}
608          
609         | DECIMAL:dec
610         {:
611         debugMessage(PRODSTRING);
612         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("decimal").addChild(dec).getRoot();
613         :}
614          
615         | STRING:str
616         {:
617         debugMessage(PRODSTRING);
618         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("string").addChild(str).getRoot();
619         :}
620          
621         | CHAR:chr
622         {:
623         debugMessage(PRODSTRING);
624         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("char").addChild(chr).getRoot();
625         :}
626          
627         | LITERAL OPENPAREN ID:literal CLOSEPAREN
628         {:
629         debugMessage(PRODSTRING);
630         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("token").addChild(literal).getRoot();
631         :}
632         ;