bison マニュアルの中間記法電卓
JFlex を使って
%% %class Scanner %implements Test.yyInput %type int %eofval{ return YYEOF; %eofval} %{ private int token; protected Double value; public boolean advance() throws java.io.IOException { token = yylex(); return token != YYEOF; } public int token() { return token; } public Object value() { return value; } %} space = [\ \t\b\015]+ digit = [0-9] integer = {digit}+ real = ({digit}+"."{digit}*|{digit}*"."{digit}+) %% {space} { } {integer}|{real} { value = new Double(yytext()); return Test.NUM; } .|\n { value = null; return yytext().charAt(0); }
と、
%{ 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(new InputStreamReader(System.in)); try { new Test().yyparse(scanner); } catch (IOException ie) { ie.printStackTrace(); } catch (yyException ye) { System.err.println(ye); } } }
で、
4 + 4.5 - (34/(8*3+-3)) 6.880952380952381 -56 + 2 -54.0 3 ^ 2 9.0