bison マニュアルの逆ポーランド記法電卓
bison マニュアルの逆ポーランド記法電卓を
JFlex の examples に入っていたコードなどを参考に記述
CUP ファイルは、
import java_cup.runtime.*; terminal OTHERS, PLUS, MINUS, MULT, DIV, EXPON, N, EOL; terminal Double NUMBER; non terminal Object input, line; non terminal Double exp; input ::= | input line ; line ::= EOL | exp:e EOL {: System.out.println("\t" + e); :} | error EOL ; exp ::= NUMBER:n {: RESULT = n; :} | exp:e1 exp:e2 PLUS {: RESULT = new Double(e1.doubleValue() + e2.doubleValue()); :} | exp:e1 exp:e2 MINUS {: RESULT = new Double(e1.doubleValue() - e2.doubleValue()); :} | exp:e1 exp:e2 MULT {: RESULT = new Double(e1.doubleValue() * e2.doubleValue()); :} | exp:e1 exp:e2 DIV {: RESULT = new Double(e1.doubleValue() / e2.doubleValue()); :} | exp:e1 exp:e2 EXPON {: RESULT = new Double(Math.pow(e1.doubleValue(), e2.doubleValue())); :} | exp:e N {: RESULT = new Double(-e.doubleValue()); :} ;
JFlex ファイルは、
import java_cup.runtime.*; %% %{ private Symbol symbol(int type) { return new Symbol(type, yyline, yycolumn); } private Symbol symbol(int type, Object value) { return new Symbol(type, yyline, yycolumn, value); } %} %class Lexer %unicode %line %column %cup %% [0-9]+ { return symbol(sym.NUMBER, new Double(yytext())); } [0-9]+\.[0-9]+ { return symbol(sym.NUMBER, new Double(yytext())); } "+" { return symbol(sym.PLUS); } "-" { return symbol(sym.MINUS); } "*" { return symbol(sym.MULT); } "/" { return symbol(sym.DIV); } "^" { return symbol(sym.EXPON); } "n" { return symbol(sym.N); } \n { return symbol(sym.EOL); } [\t ]* { } . { return symbol(sym.OTHERS); }
Java ファイルは、
import java.io.*; class Main { static public void main(String argv[]) { parser p; try { if (argv.length > 0) { p = new parser(new Lexer(new FileReader(argv[0]))); } else { p = new parser(new Lexer(new InputStreamReader(System.in))); } Object result = p.parse().value; } catch (Exception e) { e.printStackTrace(); } } }
で、
4 9 + 3 7 + 3 4 5 *+- 3 7 + 3 4 5 * + - n 5 6 / 4 n + 3 4 ^ 1.2 3.4 + 0.2 3.4 +
を入力すると、
13.0 -13.0 13.0 -3.1666666666666665 81.0 4.6 3.6