MCC files
[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 ISVALID;
147     terminal FOR;
148     terminal TO;
149     terminal CAST;
150
151     terminal PARAM;
152     terminal STRUCTURE;
153     terminal RESERVED;
154     terminal BIT;
155     terminal BYTE;
156     terminal SHORT;
157       
158     terminal LABEL;
159     terminal INT;
160     terminal SUBTYPE;
161     terminal OF;
162
163     terminal SEMICOLON;
164     terminal COLON;
165
166     terminal SET;
167     terminal ARROW;
168     terminal MANY;
169     terminal BAR;
170
171     terminal PARTITION;
172     terminal ELEMENT;
173     terminal DELAY;
174     terminal STATIC;
175
176     terminal NULL;
177     terminal CRASH;
178
179 // NON-TERMINALS /////////////////////////////////////////////////////////
180
181 /*
182                 TYPE                    NAME
183 ------------------------------------------------------------------------*/
184 nonterminal     ParseNode               constraints;
185 nonterminal     ParseNode               constraint;
186 nonterminal     ParseNode               optcrash;
187 nonterminal     ParseNode               quantifiers;
188 nonterminal     ParseNode               quantifier;
189 nonterminal     ParseNode               set;
190 nonterminal     ParseNode               listofliterals;
191 nonterminal     ParseNode               literal;
192 nonterminal     ParseNode               body;
193 nonterminal     ParseNode               predicate;
194 nonterminal     ParseNode               setexpr;
195 //nonterminal   ParseNode               limitedcompare;
196 nonterminal     ParseNode               compare;
197 nonterminal     ParseNode               expr;
198 nonterminal     ParseNode               operator;
199 nonterminal     ParseNode               relations;
200 //nonterminal   ParseNode               type;
201
202 precedence left OR;
203 precedence left AND;
204 precedence right EQ, NE; 
205 precedence right LT, LE, GE, GT;
206 precedence left ADD, SUB;
207 precedence left MULT, DIV;
208 precedence left NOT;
209 precedence left DOT, DOTINV;
210
211 // PRODUCTION RULES  /////////////////////////////////////////////////////
212
213 constraints ::=
214             constraints:constraints constraint:constraint
215             {:
216             debugMessage(PRODSTRING);
217             constraints.addChild(constraint);
218             RESULT = constraints;
219             :}
220             | constraint:constraint
221             {:
222             debugMessage(PRODSTRING);
223             ParseNode constraints = new ParseNode("constraints", parser.curLine(1));
224             constraints.addChild(constraint);
225             RESULT = constraints;
226             :}
227             ;
228
229 constraint ::=
230             optcrash:crash OPENBRACKET quantifiers:quantifiers CLOSEBRACKET COMMA body:body SEMICOLON
231             {:
232             debugMessage(PRODSTRING);
233             ParseNode constraint = new ParseNode("constraint", parser.curLine(7));
234             if (crash != null) {
235              constraint.addChild(crash);
236             }
237             if (quantifiers != null) {
238              constraint.addChild(quantifiers);
239             }
240             constraint.addChild(body);
241             RESULT = constraint;
242             :}
243             ;
244
245 optcrash ::=
246          CRASH
247          {:
248          debugMessage(PRODSTRING);
249          RESULT = new ParseNode("crash", parser.curLine(1));
250          :}
251          | /* nothing */
252          {:
253          debugMessage(PRODSTRING);
254          RESULT = null;
255          :}
256          ;
257
258 quantifiers ::=
259             quantifiers:quantifiers COMMA quantifier:quantifier
260             {:
261             debugMessage(PRODSTRING);
262             quantifiers.addChild(quantifier);
263             RESULT = quantifiers;
264             :}
265             
266             | quantifier:quantifier
267             {:
268             debugMessage(PRODSTRING);
269             ParseNode quantifiers = new ParseNode("quantifiers", parser.curLine(1));
270             quantifiers.addChild(quantifier);
271             RESULT = quantifiers;
272             :}
273             
274             | 
275             {:
276             debugMessage(PRODSTRING);
277             RESULT = null;
278             :}
279             ;   
280
281 quantifier ::= 
282            FORALL ID:var IN set:set
283            {:
284            debugMessage(PRODSTRING);
285            ParseNode q = new ParseNode("quantifier", parser.curLine(4));
286            q.addChild("forall", parser.curLine(4));
287            q.addChild("var", parser.curLine(3)).addChild(var);
288            q.addChild(set);
289            RESULT = q;
290            :}
291            ;
292
293 set ::=
294     ID:setname
295     {:
296     debugMessage(PRODSTRING);
297     ParseNode set = new ParseNode("set", parser.curLine(1));
298     set.addChild("name").addChild(setname);
299     RESULT = set;
300     :}
301     | OPENBRACE listofliterals:list CLOSEBRACE
302     {:
303     debugMessage(PRODSTRING);
304     ParseNode set = new ParseNode("set", parser.curLine(3));
305     set.addChild(list);
306     RESULT = set;
307     :}
308     ;
309     
310
311 listofliterals ::=
312                listofliterals:list COMMA literal:literal
313                {:
314                debugMessage(PRODSTRING);
315                list.addChild(literal);
316                RESULT = list;
317                :}
318                | literal:literal
319                {: 
320                debugMessage(PRODSTRING);
321                ParseNode list = new ParseNode("listofliterals", parser.curLine(1));
322                list.addChild(literal);
323                RESULT = list;
324                :}
325                ;
326
327 body ::=
328      body:body1 AND body:body2
329         {:
330         debugMessage(PRODSTRING);
331         ParseNode body = new ParseNode("body", parser.curLine(3));
332         body.addChild("and").addChild("left", parser.curLine(3)).addChild(body1);
333         body.getChild("and").addChild("right", parser.curLine(1)).addChild(body2);
334         RESULT = body;
335         :}
336      | body:body1 OR body:body2
337         {:
338         debugMessage(PRODSTRING);
339         ParseNode body = new ParseNode("body", parser.curLine(3));
340         body.addChild("or").addChild("left", parser.curLine(3)).addChild(body1);
341         body.getChild("or").addChild("right", parser.curLine(1)).addChild(body2);
342         RESULT = body;
343         :}
344      | NOT body:body1
345         {:
346         debugMessage(PRODSTRING);
347         ParseNode body = new ParseNode("body", parser.curLine(2));
348         body.addChild("not").addChild(body1);
349         RESULT = body;
350         :}
351      | OPENPAREN body:body CLOSEPAREN
352         {:
353         debugMessage(PRODSTRING);
354         RESULT = body;
355         :}
356      | predicate:predicate
357         {:
358         debugMessage(PRODSTRING);
359         ParseNode body = new ParseNode("body", parser.curLine(1));
360         body.addChild(predicate);
361         RESULT = body;
362         :}
363      ;
364
365 predicate ::=
366
367         ID:var IN setexpr:setexpr
368         {:
369         debugMessage(PRODSTRING);
370         ParseNode inclusion = (new ParseNode("predicate", parser.curLine(3))).addChild("inclusion");
371         inclusion.addChild("quantifiervar", parser.curLine(3)).addChild(var);
372         inclusion.addChild(setexpr);
373         RESULT = inclusion.getRoot();
374         :}
375      
376         | SIZEOF OPENPAREN setexpr:setexpr CLOSEPAREN
377         {:
378         ParseNode expr = new ParseNode("expr", parser.curLine(4));
379         expr.addChild("sizeof").addChild(setexpr);
380         RESULT = expr;
381         :}
382
383         | 
384         {:
385         debugMessage(PRODSTRING);
386         ParseNode comparison = (new ParseNode("predicate", parser.curLine(3))).addChild("comparison");
387         comparison.addChild("compare", parser.curLine(2)).addChild(compare);
388         comparison.addChild("left", parser.curLine(3)).addChild(leftexpr);
389         comparison.addChild("right", parser.curLine(1)).addChild(rightexpr);
390         RESULT = comparison.getRoot();
391         :}
392           ;
393
394 setexpr ::=
395         ID:setname
396         {:
397         debugMessage(PRODSTRING);
398         ParseNode set = new ParseNode("setexpr", parser.curLine(1));
399         set.addChild("set").addChild(setname);
400         RESULT = set;
401         :}
402         | ID:var DOT ID:relation
403         {:
404         debugMessage(PRODSTRING);
405         ParseNode set = new ParseNode("setexpr", parser.curLine(3));
406         set.addChild("dot").addChild("quantifiervar", parser.curLine(3)).addChild(var);
407         set.getChild("dot").addChild("relation", parser.curLine(1)).addChild(relation);
408         RESULT = set;
409         :}
410         | ID:var DOTINV ID:relation
411         {:
412         debugMessage(PRODSTRING);
413         ParseNode set = new ParseNode("setexpr", parser.curLine(3));
414         set.addChild("dotinv").addChild("quantifiervar", parser.curLine(3)).addChild(var);
415         set.getChild("dotinv").addChild("relation", parser.curLine(1)).addChild(relation);
416         RESULT = set;
417         :}
418         ;
419
420
421
422 relations ::= 
423          
424          relations:relations DOT ID:relation
425          {:
426          debugMessage(PRODSTRING);
427          relations.insertChild(relation);
428          RESULT = relations;
429          :}
430
431          | relations:relations DOTINV ID:relation
432          {:
433          debugMessage(PRODSTRING);
434          relations.insertChild(relation).addChild("inv");
435          RESULT = relations;
436          :}
437
438          | ID:relation
439          {:
440          debugMessage(PRODSTRING);
441          ParseNode relations = new ParseNode("relations", parser.curLine(1));
442          relations.addChild(relation);
443          RESULT = relations;
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      | ID:var DOT relations:relations
472      {:
473      debugMessage(PRODSTRING);
474      ParseNode expr = new ParseNode("expr", parser.curLine(3));
475      ParseNode relation = new ParseNode("relation");
476      expr.addChild(relation);
477      relation.addChild("quantifiervar", parser.curLine(3)).addChild(var);
478      relation.addChild(relations);
479      RESULT = expr;
480      :}
481
482      | ID:var DOTINV relations:relations
483      {:
484      debugMessage(PRODSTRING);
485      ParseNode expr = new ParseNode("expr", parser.curLine(3));
486      ParseNode relation = new ParseNode("relation");
487      expr.addChild(relation);
488      relation.addChild("quantifiervar", parser.curLine(3)).addChild(var);
489      relation.addChild(relations);
490      relations.getChildren().elementAt(0).addChild("inv");
491      RESULT = expr;
492      :}
493         
494      | expr:expr1 operator:operator expr:expr2
495         {:
496         debugMessage(PRODSTRING);
497         ParseNode op = (new ParseNode("expr", parser.curLine(3))).addChild("operator");
498         op.addChild("op").addChild(operator);
499         op.addChild("left", parser.curLine(3)).addChild(expr1);
500         op.addChild("right", parser.curLine(1)).addChild(expr2);
501         RESULT = op.getRoot();
502         :}
503
504
505      ;        
506
507 operator ::=
508           ADD 
509         {:
510         debugMessage(PRODSTRING);
511         RESULT = new ParseNode("add", parser.curLine(1));
512         :}
513           | SUB
514         {:
515         debugMessage(PRODSTRING);
516         RESULT = new ParseNode("sub", parser.curLine(1));
517         :}
518           | MULT
519         {:
520         debugMessage(PRODSTRING);
521         RESULT = new ParseNode("mult", parser.curLine(1));
522         :}
523           | DIV
524         {:
525         debugMessage(PRODSTRING);
526         RESULT = new ParseNode("div", parser.curLine(1));
527         :}
528           ;
529
530 compare ::= 
531         LT
532         {:
533         debugMessage(PRODSTRING);
534         RESULT = new ParseNode("lt", parser.curLine(1));
535         :}
536         | GT
537         {:
538         debugMessage(PRODSTRING);
539         RESULT = new ParseNode("gt", parser.curLine(1));
540         :}
541         | LE
542         {:
543         debugMessage(PRODSTRING);
544         RESULT = new ParseNode("le", parser.curLine(1));
545         :}
546         | GE
547         {:
548         debugMessage(PRODSTRING);
549         RESULT = new ParseNode("ge", parser.curLine(1));
550         :}
551         | EQ
552         {:
553         debugMessage(PRODSTRING);
554         RESULT = new ParseNode("eq", parser.curLine(1));
555         :}
556         | NE
557         {:
558         debugMessage(PRODSTRING);
559         RESULT = new ParseNode("ne", parser.curLine(1));
560         :}
561         ;
562         
563 literal ::=
564          TRUE
565         {:
566         debugMessage(PRODSTRING);
567         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("boolean").addChild("true").getRoot();
568         :}
569          | DECIMAL:dec
570         {:
571         debugMessage(PRODSTRING);
572         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("decimal").addChild(dec).getRoot();
573         :}
574          | STRING:str
575         {:
576         debugMessage(PRODSTRING);
577         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("string").addChild(str).getRoot();
578         :}
579          | CHAR:chr
580         {:
581         debugMessage(PRODSTRING);
582         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("char").addChild(chr).getRoot();
583         :}
584          | ID:literal
585         {:
586         debugMessage(PRODSTRING);
587         RESULT = (new ParseNode("literal", parser.curLine(1))).addChild("token").addChild(literal).getRoot();
588         :}
589         ;