/* In this version, we build abstract syntax trees. We also add the operator for unary minus for negative numbers */ import java_cup.runtime.*; import java.io.*; parser code {: String intext; // these vars must be declared here and instantiated below: Yylex scanner; :}; init with {: try { BufferedReader lineinput = new BufferedReader(new InputStreamReader(System.in)); intext = lineinput.readLine(); } catch (Exception ee) {} scanner = new Yylex(new StringReader(intext)); :}; scan with {: return scanner.next_token(); :}; /* grammar symbols and associated semantic value */ terminal PLUS, MINUS, TIMES, DIVIDE, LPAREN, RPAREN, DOT; terminal Double NUM; terminal UMINUS; non terminal Exp Line; non terminal Exp Ex; non terminal Exp Tx; non terminal Exp Fx; /* Operator precedence and associativity declarations: The last line have higher precedence than earliear lines. The fictional UMINUS operator binds tighter than all others */ precedence left PLUS, MINUS; precedence left TIMES, DIVIDE; precedence left UMINUS; /* grammar production rules and semantic actions */ Line ::= Ex:v1 {: RESULT = v1; System.out.println("Tree evals to "+v1.eval()); :}; Ex ::= Ex:v1 PLUS Ex:v2 {: RESULT = new plusexp(v1,v2); :} | Ex:v1 MINUS Ex:v2 {: RESULT = new minusexp(v1,v2); :} | Ex:v1 TIMES Ex:v2 {: RESULT = new multexp(v1,v2); :} | Ex:v1 DIVIDE Ex:v2 {: double x = v2.eval(); /* Note difference here as well */ if (x == 0) throw new Error("watch division by zero you bonehead!"); else RESULT = new divexp(v1,v2); :} | MINUS Ex:v1 {: RESULT = new negexp(v1); :} %prec UMINUS | LPAREN Ex:v1 RPAREN {: RESULT = v1; :} | NUM:v1 {: RESULT = new dlit(v1); /*unboxing occurs*/ :};