bison マニュアルの逆ポーランド記法電卓

自前 Scanner で

%{

import java.io.*;

public class Test {

%}

%token NUM
%type <Double> exp NUM

%%

input:    /* 空 */
        | input line
;

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

exp:      NUM           { $$ = new Double($1.doubleValue());         }
        | exp exp '+'   { $$ = new Double($1.doubleValue() + $2.doubleValue());    }
        | exp exp '-'   { $$ = new Double($1.doubleValue() - $2.doubleValue());    }
        | exp exp '*'   { $$ = new Double($1.doubleValue() * $2.doubleValue());    }
        | exp exp '/'   { $$ = new Double($1.doubleValue() / $2.doubleValue());    }
      /* べき乗関数 */
        | exp exp '^'   { $$ = new Double(Math.pow($1.doubleValue(), $2.doubleValue())); }
      /* 単項のマイナス */
        | exp 'n'       { $$ = new Double(-$1.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 9 +
	13.0
3 7 + 3 4 5 *+-
	-13.0
3 7 + 3 4 5 * + - n
	13.0
5 6 / 4 n +
	-3.1666666666666665
3 4 ^
	81.0
1.2 3.4 +
	4.6
0.2 3.4 +
	3.6
.2 3.4 +
	3.6
1. 3.4 +
	4.4
1 3.4 +
	4.4