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