bison マニュアルの中間記法電卓

自前 Scanner で

%{

import java.io.*;

public class Test {

%}

%token NUM
%type <Double> exp NUM

%left '-' '+'
%left '*' '/'
%left NEG     /* negation--単項マイナス */
%right '^'    /* べき乗関数        */

%%

input:    /* 空 */
        | input line
;

line:     '\n'
        | exp   '\n' { System.out.println("\t" + $1); }
        | error '\n' { yyErrorFlag = 0; }
;

exp:      NUM                { $$ = new Double($1.doubleValue());         }
        | exp '+' exp        { $$ = new Double($1.doubleValue() + $3.doubleValue());    }
        | exp '-' exp        { $$ = new Double($1.doubleValue() - $3.doubleValue());    }
        | exp '*' exp        { $$ = new Double($1.doubleValue() * $3.doubleValue());    }
        | exp '/' exp        { $$ = new Double($1.doubleValue() / $3.doubleValue());    }
        | '-' exp  %prec NEG { $$ = new Double(-$2.doubleValue());        }
        | exp '^' exp        { $$ = new Double(Math.pow($1.doubleValue(), $3.doubleValue())); }
        | '(' exp ')'        { $$ = new Double($2.doubleValue());         }
;

%%

  public static void main (String args []) {
    Scanner scanner = new Scanner();
    try {
      new Test().yyparse(scanner);
    } catch (IOException ie) { ie.printStackTrace(); }
      catch (yyException ye) { System.err.println(ye); }
  }

}


class Scanner implements Test.yyInput {
  private int ch = 0;

  public Scanner() {
  }

  public boolean advance() throws IOException {
    return true;
  }

  public int token() {
    value = null;

    for (;;) {
      int c = getch();
      if (c < 0)
        return 0;
      else if (c == ' ' || c == '\t')
        ;
      else if (Character.isDigit((char)c) || c == '.') {
        int n = 0;
        char[] buf = new char[100];
        while (Character.isDigit((char)c) || c == '.') {
          buf[n++] = (char)c;
          if (c == '.') break;
          c = getch();
        }
        if (c == '.') {
          c = getch();
          while (Character.isDigit((char)c)) {
            buf[n++] = (char)c;
            c = getch();
          }
        }
        ungetch(c);
        if (n == 1 && buf[0] == '.') {
          return '.';
        } else {
          value = new Double(new String(buf, 0, n));
          return Test.NUM;
        }
      }
      else
        return c;
    }
  }

  protected Object value;

  public Object value() {
    return value;
  }

  private int getch() {
    int c = ch;
    if (c != 0) {
      ch = 0;
      return c;
    }
    try {
      return System.in.read();
    } catch (java.io.IOException e) {
      throw new Error(e.getMessage());
    }
  }

  private void ungetch(int c) { ch = c; }
}

で、

4 + 4.5 - (34/(8*3+-3))
	6.880952380952381
-56 + 2
	-54.0
3 ^ 2
	9.0