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