Added add_ast_action

This commit is contained in:
yhirose 2020-06-06 23:13:57 -04:00
parent c1f087a91e
commit feebe2bb0f

View File

@ -553,7 +553,8 @@ struct SemanticValues : protected std::vector<any> {
// Transform the semantic value vector to another vector // Transform the semantic value vector to another vector
template <typename T> template <typename T>
std::vector<T> transform(size_t beg = 0, size_t end = static_cast<size_t>(-1)) const { std::vector<T> transform(size_t beg = 0,
size_t end = static_cast<size_t>(-1)) const {
std::vector<T> r; std::vector<T> r;
end = (std::min)(end, size()); end = (std::min)(end, size());
for (size_t i = beg; i < end; i++) { for (size_t i = beg; i < end; i++) {
@ -3646,6 +3647,32 @@ private:
struct EmptyType {}; struct EmptyType {};
typedef AstBase<EmptyType> Ast; typedef AstBase<EmptyType> Ast;
template <typename T = Ast>
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<T>(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<T>(
sv.path, line.first, line.second, name,
sv.transform<std::shared_ptr<T>>(), 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 * parser
*---------------------------------------------------------------------------*/ *---------------------------------------------------------------------------*/
@ -3775,32 +3802,7 @@ public:
template <typename T = Ast> parser &enable_ast() { template <typename T = Ast> parser &enable_ast() {
for (auto &x : *grammar_) { for (auto &x : *grammar_) {
const auto &name = x.first; add_ast_action(x.first.c_str(), x.second);
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<T>(
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<T>(
sv.path, line.first, line.second, name.c_str(),
sv.transform<std::shared_ptr<T>>(),
std::distance(sv.ss, sv.c_str()), sv.length(), sv.choice_count(),
sv.choice());
for (auto node : ast->nodes) {
node->parent = ast;
}
return ast;
};
}
} }
return *this; return *this;
} }