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