構文木を作る その2
Hamigaki.Bjamの改良用にSandboxにディレクトリを追加しました。
hamigaki/bjam2
svn copyとかすると前のコードが枷になって大胆な変更がやりにくいので、必要な箇所を切り貼りしながら書き直していき、最終的にtrunkにマージする形をとります。
今日はbjam_grammarからセマンティックアクションを取り除き、構文木を作るところまでやりました。
前のバージョンでは、式のパースと評価をbjam_expression_grammarという別の文法で行っていましたが、今回はパースしかしないのでbjam_grammarにまとめました。
以下、お試しコード。
// 注: bjam2は仮名。trunkにマージする際はbjamに戻す。 #include <hamigaki/bjam2/grammars/bjam_grammar.hpp> #include <hamigaki/bjam2/util/skip_parser.hpp> #include <boost/spirit/tree/tree_to_xml.hpp> #include <boost/spirit/tree/parse_tree.hpp> #include <exception> #include <iostream> #include <map> namespace bjam = hamigaki::bjam2; namespace spirit = boost::spirit; int main() { try { bjam::bjam_grammar g; bjam::skip_parser skip; std::map<spirit::parser_id, std::string> rule_names; rule_names[g.run_id] = "run"; rule_names[g.block_id] = "block"; rule_names[g.rules_id] = "rules"; rule_names[g.local_set_stmt_id] = "local_set_stmt"; rule_names[g.assign_list_id] = "assign_list"; rule_names[g.arglist_id] = "arglist"; rule_names[g.rule_id] = "rule"; rule_names[g.include_stmt_id] = "include_stmt"; rule_names[g.invoke_stmt_id] = "invoke_stmt"; rule_names[g.set_stmt_id] = "set_stmt"; rule_names[g.set_on_stmt_id] = "set_on_stmt"; rule_names[g.assign_id] = "assign"; rule_names[g.for_stmt_id] = "for_stmt"; rule_names[g.switch_stmt_id] = "switch_stmt"; rule_names[g.cases_id] = "cases"; rule_names[g.module_stmt_id] = "module_stmt"; rule_names[g.class_stmt_id] = "class_stmt"; rule_names[g.while_stmt_id] = "while_stmt"; rule_names[g.if_stmt_id] = "if_stmt"; rule_names[g.rule_stmt_id] = "rule_stmt"; rule_names[g.on_stmt_id] = "on_stmt"; rule_names[g.actions_stmt_id] = "actions_stmt"; rule_names[g.expr_id] = "expr"; rule_names[g.and_expr_id] = "and_expr"; rule_names[g.eq_expr_id] = "eq_expr"; rule_names[g.rel_expr_id] = "rel_expr"; rule_names[g.not_expr_id] = "not_expr"; rule_names[g.prim_expr_id] = "prim_expr"; rule_names[g.lol_id] = "lol"; rule_names[g.list_id] = "list"; rule_names[g.non_punct_id] = "non_punct"; rule_names[g.arg_id] = "arg"; rule_names[g.func_id] = "func"; rule_names[g.eflags_id] = "eflags"; rule_names[g.bindlist_id] = "bindlist"; spirit::tree_parse_info<> info = spirit::pt_parse("ECHO ;", g, skip); spirit::tree_to_xml(std::cout, info.trees, "", rule_names); } catch (const std::exception& e) { std::cerr << "Error: " << e.what() << std::endl; } }
実行結果
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE parsetree SYSTEM "parsetree.dtd"> <parsetree version="1.0"> <parsenode> <parsenode rule="rules"> <parsenode rule="rule"> <parsenode rule="invoke_stmt"> <parsenode rule="invoke_stmt"> <value>ECHO</value> </parsenode> <parsenode rule="invoke_stmt"> <value>;</value> </parsenode> </parsenode> </parsenode> </parsenode> </parsenode> </parsetree>