1 %{
2 import java.lang.Math;
3 import java.io.*;
4 import java.util.StringTokenizer;
5 %}
6 
7 /* YACC Declarations */
8 %token NUM
9 %left '-' '+'
10 %left '*' '/'
11 %left NEG     /* negation--unary minus */
12 %right '^'    /* exponentiation        */
13 
14 /* Grammar follows */
15 %%
16 input:    /* empty string */
17              | input line
18      ;
19 
20 line:     '\n'
21           | exp '\n'  { System.out.println(" " + $1.dval + " "); }
22      ;
23 
24 exp:      NUM                { $$ = $1;         }
25              | exp '+' exp        { $$ = new ParserVal($1.dval + $3.dval);    }
26              | exp '-' exp        { $$ = new ParserVal($1.dval - $3.dval);    }
27              | exp '*' exp        { $$ = new ParserVal($1.dval * $3.dval);    }
28              | exp '/' exp        { $$ = new ParserVal($1.dval / $3.dval);    }
29              | '-' exp  %prec NEG { $$ = new ParserVal(-$2.dval);        }
30              | exp '^' exp        { $$ = new ParserVal(Math.pow($1.dval, $3.dval)); }
31              | '(' exp ')'        { $$ = $2;      }
32      ;
33 %%
34 
35 String ins;
36 StringTokenizer st;
37 
yyerror(String s)38 void yyerror(String s)
39 {
40   System.out.println("par:"+s);
41 }
42 
43 boolean newline;
yylex()44 int yylex()
45 {
46 String s;
47 int tok;
48 Double d;
49   //System.out.print("yylex ");
50   if (!st.hasMoreTokens())
51     if (!newline)
52       {
53       newline=true;
54       return '\n';  //So we look like classic YACC example
55       }
56     else
57       return 0;
58   s = st.nextToken();
59   //System.out.println("tok:"+s);
60   try
61     {
62     d = Double.valueOf(s);/*this may fail*/
63     yylval = new ParserVal(d.doubleValue());
64     tok = NUM;
65     }
66   catch (Exception e)
67     {
68     tok = s.charAt(0);/*if not float, return char*/
69     }
70   return tok;
71 }
72 
dotest()73 void dotest()
74 {
75 BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
76   System.out.println("BYACC/Java Calculator Demo");
77   System.out.println("Note: Since this example uses the StringTokenizer");
78   System.out.println("for simplicity, you will need to separate the items");
79   System.out.println("with spaces, i.e.:  '( 3 + 5 ) * 2'");
80   while (true)
81     {
82     System.out.print("expression:");
83     try
84       {
85       ins = in.readLine();
86       }
87     catch (Exception e)
88       {
89       }
90     st = new StringTokenizer(ins);
91     newline=false;
92     if (yyparse()!=0)
93       {
94       System.out.println("error");
95       }
96     }
97 }
98 
main(String args[])99 public static void main(String args[])
100 {
101   Parser par = new Parser(true);
102   par.dotest();
103 }
104