package MCC; import MCC.IR.ParseNode; import MCC.IR.ParseNodeVector; import java.util.*; action code {: public static boolean errors; public static boolean debug; // debugMessage: writes debug production message only if debug = true void debugMessage (String production) { if (debug) { System.out.println("Applying production: " + production); } } String unescape (String str) { StringBuffer sb = new StringBuffer(); int i; // Note that we skip the first and last characters (they're "'s) for (i = 1; i < str.length() - 1; i++) { if (str.charAt(i) == '\\') { i++; switch (str.charAt(i)) { case '\"': sb.append('\"'); break; case '\'': sb.append('\''); break; case '\\': sb.append('\\'); break; case 't': sb.append('\t'); break; case 'n': sb.append('\n'); break; default: System.err.print("Error in string literal: "); System.err.println(str.charAt(i)); System.err.println("Aborting..."); break; } } else { sb.append(str.charAt(i)); } } return sb.toString(); } :} init with {: :} parser code {: public String filename; public void syntax_error (java_cup.runtime.Symbol current) { CUP$SDLParser$actions.errors = true; Symbol symbol = (Symbol) current; report_error(filename+":"+(symbol.line+1)+": Syntax error at column " + (LineCount.getColumn(symbol.left)+1) +": " + current.value, current); System.out.println(); System.exit(0); } public void report_fatal_error (String message, Object info) { done_parsing(); report_error(message, info); CUP$SDLParser$actions.errors = true; } public int curPos () { return cur_token.left; } public int curLine (int back) { Stack st = new Stack(); int i; for (i = 0; i < back; i++) { st.push(stack.pop()); } java_cup.runtime.Symbol s; s = (java_cup.runtime.Symbol) st.peek(); for (i = 0; i < back; i++) { stack.push(st.pop()); } return LineCount.getLine(s.left); } :} // TERMINALS ///////////////////////////////////////////////////////////// terminal BAD; terminal String ID; terminal String DECIMAL; terminal String CHAR; terminal String STRING; terminal OPENBRACE; terminal CLOSEBRACE; terminal OPENPAREN; terminal CLOSEPAREN; terminal OPENBRACKET; terminal CLOSEBRACKET; terminal ADD; terminal SUB; terminal MULT; terminal DIV; terminal NOT; terminal LT; terminal GT; terminal LE; terminal GE; terminal EQ; terminal NE; terminal FORALL; terminal IN; terminal INTEST; terminal COMMA; terminal SIZEOF; terminal DOT; terminal DOTINV; terminal AND; terminal OR; terminal LITERAL; terminal IMPLIES; terminal TRUE; terminal FALSE; terminal ISVALID; terminal FOR; terminal TO; terminal CAST; terminal PARAM; terminal STRUCTURE; terminal RESERVED; terminal BIT; terminal BYTE; terminal SHORT; terminal LABEL; terminal INT; terminal SUBTYPE; terminal OF; terminal SEMICOLON; terminal COLON; terminal SET; terminal ARROW; terminal MANY; terminal BAR; terminal PARTITION; terminal ELEMENT; terminal DELAY; terminal STATIC; terminal NULL; terminal CRASH; // NON-TERMINALS ///////////////////////////////////////////////////////// /* TYPE NAME ------------------------------------------------------------------------*/ nonterminal ParseNode spacedefs; nonterminal ParseNode space; nonterminal ParseNode mult; nonterminal ParseNode optstatic; nonterminal ParseNode optpartition; nonterminal ParseNode setlist; nonterminal ParseNode type; nonterminal ParseNode optrange; precedence left OR; precedence left AND; precedence right EQ, NE; precedence right LT, LE, GE, GT; precedence left ADD, SUB; precedence left MULT, DIV; precedence left NOT; precedence left DOT; // PRODUCTION RULES ///////////////////////////////////////////////////// start with spacedefs; spacedefs ::= spacedefs:spacedefs space:space {: debugMessage(PRODSTRING); spacedefs.addChild(space); RESULT = spacedefs; :} | space:space {: debugMessage(PRODSTRING); ParseNode spacedefs = new ParseNode("space", parser.curLine(1)); spacedefs.addChild(space); RESULT = spacedefs; :} ; space ::= SET ID:setname OPENPAREN type:settype CLOSEPAREN SEMICOLON {: debugMessage(PRODSTRING); ParseNode set = new ParseNode("setdefinition", parser.curLine(6)); set.addChild("name", parser.curLine(5)).addChild(setname); set.addChild(settype); RESULT = set; :} | SET ID:setname OPENPAREN type:settype CLOSEPAREN COLON optpartition:partition setlist:setlist SEMICOLON {: debugMessage(PRODSTRING); ParseNode set = new ParseNode("setdefinition", parser.curLine(8)); set.addChild("name", parser.curLine(7)).addChild(setname); set.addChild(settype); if (partition != null) set.addChild(partition); if (setlist != null) set.addChild(setlist); RESULT = set; :} | ID:name optstatic:optstatic COLON type:domain ARROW type:range optrange:optrange SEMICOLON {: debugMessage(PRODSTRING); ParseNode relation = new ParseNode("relationdefinition", parser.curLine(8)); if (optstatic != null) relation.addChild(optstatic); relation.addChild("name", parser.curLine(7)).addChild(name); relation.addChild("domain").addChild(domain); relation.addChild("range").addChild(range); if (optrange != null) { relation.getChild("domain").addChild(optrange.getChild("domainmult")); relation.getChild("range").addChild(optrange.getChild("rangemult")); } RESULT = relation; :} ; optrange ::= OPENPAREN mult:domainmult ARROW mult:rangemult CLOSEPAREN {: debugMessage(PRODSTRING); ParseNode optrange = new ParseNode("optrange", parser.curLine(5)); optrange.addChild("domainmult").addChild(domainmult); optrange.addChild("rangemult").addChild(rangemult); RESULT = optrange; :} | /* nothing */ {: RESULT = null; :} ; mult ::= DECIMAL:one {: debugMessage(PRODSTRING); ParseNode mult = new ParseNode("mult", parser.curLine(1)); mult.addChild(one); RESULT = mult; :} | MANY {: debugMessage(PRODSTRING); ParseNode mult = new ParseNode("mult", parser.curLine(1)); mult.addChild("many"); RESULT = mult; :} ; optstatic ::= STATIC {: debugMessage(PRODSTRING); RESULT = new ParseNode("static", parser.curLine(1)); :} | /* nothing */ {: debugMessage(PRODSTRING); RESULT = null; :} ; optpartition ::= PARTITION {: debugMessage(PRODSTRING); RESULT = new ParseNode("partition", parser.curLine(1)); :} | /* nothing */ {: debugMessage(PRODSTRING); RESULT = null; :} ; setlist ::= setlist:setlist BAR ID:set {: debugMessage(PRODSTRING); setlist.addChild(set, parser.curLine(1)); RESULT = setlist; :} | ID:set {: debugMessage(PRODSTRING); ParseNode setlist = new ParseNode("setlist"); setlist.addChild(set, parser.curLine(1)); RESULT = setlist; :} | {: debugMessage(PRODSTRING); RESULT = null; :} ; type ::= BIT {: debugMessage(PRODSTRING); ParseNode type = new ParseNode("type", parser.curLine(1)); type.addChild("bit"); RESULT = type; :} | BYTE {: debugMessage(PRODSTRING); ParseNode type = new ParseNode("type", parser.curLine(1)); type.addChild("byte"); RESULT = type; :} | SHORT {: debugMessage(PRODSTRING); ParseNode type = new ParseNode("type", parser.curLine(1)); type.addChild("short"); RESULT = type; :} | INT {: debugMessage(PRODSTRING); ParseNode type = new ParseNode("type", parser.curLine(1)); type.addChild("int"); RESULT = type; :} | ID:typename {: debugMessage(PRODSTRING); ParseNode type = new ParseNode("type", parser.curLine(1)); type.addChild(typename); RESULT = type; :} ;