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