// 属性値の型 %semantic double %token NUMBER EOL /* jacc cannot handle '\n' properly */ %token FOO /* token の優先順位 */ %left '+' '-' FOO %left '*' '/' %% /* 通常の BNF の → の代わりに : を書く。各 BNF は ; で区切る。 */ /* 最初に start symbol を書く */ input : /* 空 */ | input line EOL {} ; /* $$ は左辺の属性値、$n は右辺の n 番目の文法要素の属性値を表す。 */ line : /* 空 */ { System.exit(0); } | expr { System.out.printf("\t%g%n", $1); } ; expr : expr '+' expr { $$ = $1 + $3; } | expr '-' expr { $$ = $1 - $3; } | expr '*' expr { $$ = $1 * $3; } | expr '/' expr { $$ = $1 / $3; } | expr FOO expr { $$ = $1 * 256 + $3; } | '(' expr ')' { $$ = $2; } | NUMBER { $$ = $1; } ; %% /* フィールドやメソッドの定義 */ CalcParser(CalcLexer l) { lexer = l; } private CalcLexer lexer; private void yyerror(String msg) { System.out.println("エラー: " + msg); System.exit(1); } public static void main(String[] args) { CalcLexer lexer = new CalcLexer(System.in); CalcParser calc = new CalcParser(lexer); lexer.nextToken(); calc.parse(); // parse the input }