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