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