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