構文木を作る その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>