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