diff --git a/peglib.h b/peglib.h index fbd909c..73ee099 100644 --- a/peglib.h +++ b/peglib.h @@ -553,7 +553,8 @@ struct SemanticValues : protected std::vector { // Transform the semantic value vector to another vector template - std::vector transform(size_t beg = 0, size_t end = static_cast(-1)) const { + std::vector transform(size_t beg = 0, + size_t end = static_cast(-1)) const { std::vector r; end = (std::min)(end, size()); for (size_t i = beg; i < end; i++) { @@ -3646,6 +3647,32 @@ private: struct EmptyType {}; typedef AstBase Ast; +template +void add_ast_action(const char *name, Definition &rule) { + if (!rule.action) { + rule.action = [&](const SemanticValues &sv) { + auto line = sv.line_info(); + + if (rule.is_token()) { + return std::make_shared(sv.path, line.first, line.second, + name, sv.token(), + std::distance(sv.ss, sv.c_str()), + sv.length(), sv.choice_count(), sv.choice()); + } + + auto ast = std::make_shared( + sv.path, line.first, line.second, name, + sv.transform>(), std::distance(sv.ss, sv.c_str()), + sv.length(), sv.choice_count(), sv.choice()); + + for (auto node : ast->nodes) { + node->parent = ast; + } + return ast; + }; + } +} + /*----------------------------------------------------------------------------- * parser *---------------------------------------------------------------------------*/ @@ -3775,32 +3802,7 @@ public: template parser &enable_ast() { for (auto &x : *grammar_) { - const auto &name = x.first; - auto &rule = x.second; - - if (!rule.action) { - rule.action = [&](const SemanticValues &sv) { - auto line = sv.line_info(); - - if (rule.is_token()) { - return std::make_shared( - sv.path, line.first, line.second, name.c_str(), sv.token(), - std::distance(sv.ss, sv.c_str()), sv.length(), - sv.choice_count(), sv.choice()); - } - - auto ast = std::make_shared( - sv.path, line.first, line.second, name.c_str(), - sv.transform>(), - std::distance(sv.ss, sv.c_str()), sv.length(), sv.choice_count(), - sv.choice()); - - for (auto node : ast->nodes) { - node->parent = ast; - } - return ast; - }; - } + add_ast_action(x.first.c_str(), x.second); } return *this; }