bison マニュアルの多機能電卓
JFlex を使って
%% %class Scanner %implements Test.yyInput %type int %eofval{ return YYEOF; %eofval} %{ private int token; protected Object 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}+) id = [a-zA-Z][a-zA-Z0-9]* %% {space} { } {integer}|{real} { value = new Double(yytext()); return Test.NUM; } {id} { Obj s = Test.getsym(yytext()); if (s == null) { s = Test.putsym(yytext(), Test.VAR); } value = s; return s.type; } .|\n { value = null; return yytext().charAt(0); }
と、
%{ import java.io.*; import java.util.*; class Obj { public String name; public int type; public double val; Obj(String s, int t, double v) { name = s; type = t; val = v; } } public class Test { // class Obj { // public String name; // public int type; // public double val; // // Obj(String s, int t, double v) { // name = s; type = t; val = v; // } // } %} %token NUM %type <Double> exp NUM %token <Obj> VAR FNCT /* 変数と関数 */ %right '=' %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()); } | VAR { $$ = new Double($1.val); } | VAR '=' exp { $$ = new Double($3.doubleValue()); $1.val = $3.doubleValue(); } | FNCT '(' exp ')' { $$ = new Double(func($1.name, $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 '/' 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()); } ; %% private static Map sym = new HashMap(); private static void init_table() { putsym("sin", FNCT); putsym("cos", FNCT); putsym("atan", FNCT); putsym("ln", FNCT); putsym("exp", FNCT); putsym("sqrt", FNCT); } public static Obj putsym(String sym_name, int sym_type) { Obj x = new Obj(sym_name, sym_type, 0); sym.put(sym_name, x); return x; } public static Obj getsym(String sym_name) { if (sym.containsKey(sym_name)) { return (Obj)sym.get(sym_name); } else { return null; } } private double func(String sym_name, double v) { if (sym_name == "sin") { return Math.sin(v); } else if (sym_name == "cos") { return Math.cos(v); } else if (sym_name == "atan") { return Math.atan(v); } else if (sym_name == "ln") { return Math.log(v); } else if (sym_name == "exp") { return Math.exp(v); } else if (sym_name == "sqrt") { return Math.sqrt(v); } else { return 0; } } public static void main (String args []) { init_table(); 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); } } }
で、
pi = 3.141592653589 3.141592653589 sin(pi) 7.932657934721266E-13 alpha = beta1 = 2.3 2.3 alpha 2.3 ln(alpha) 0.8329091229351039 exp(ln(beta1)) 2.3