■
前作った演算子順位パーサのインターフェースを昨日作ったパーサのインターフェースと組み合わせられるように変更。
これで、昨日の括弧付き四則演算のパーサが
var input = stream.open_rstream( options.input_filename ); var lextable = [ ["[0-9]+":`TOK_DIGIT], ["\\+":`TOK_PLUS], ["-":`TOK_MINUS], ["\\*":`TOK_MUL], ["/":`TOK_DIV], ["\\(":`TOK_LPAREN], ["\\)":`TOK_RPAREN], ["=":`TOK_ASSIGN], ["[ \t]+":null], [null: `TOK_EOF] ]; var lexer = Lex.generate_analyzer( lextable ); var lexstream = Lex.new_lex_stream( lexer, input ); function digit(token) { var str = token.match_data[0]; var num = lang.lexer.lex_number( str ); return [true:num]; } using gcc; var oppre_table = [ [`L, [`TOK_MUL:MULT_EXPR],[`TOK_DIV:CEIL_DIV_EXPR]], // L は左結合 [`L, [`TOK_PLUS:PLUS_EXPR],[`TOK_MINUS:MINUS_EXPR]], [`R, [`TOK_ASSIGN:MODIFY_EXPR]] // Rは右結合 ]; function call_toplev(l) {return toplev(l);} var digit_expr = Parser.token(`TOK_DIGIT,digit); var paren_expr = Parser.sequence( [Parser.token(`TOK_LPAREN), call_toplev, Parser.token(`TOK_RPAREN)], function(e) { return [true:e]; } ); var term_expr = Parser.select( [digit_expr,paren_expr] ); var binary_expr = Parser.create_oppre_parser( oppre_table, term_expr, function(e) {e.type=types.integer_type_node;} ); var toplev = binary_expr; var ret = toplev(lexstream); debug_tree( ret.chain );
こんなに簡単に!!(一部誇張表現あり)
さらに、昨日のでは適当になってた左結合も正しく動く。
これでいいのかな。昨日の再帰できない問題についても、これで十分かもしれない。call_toplevの部分。
パーサの中身はただのリストなので、それをあとから繋ぎ換えてやれば直接自分に再帰するのもできるんだけど。それは裏技ということにしておこう。