Keep selected rule id in AST

This commit is contained in:
yhirose 2018-11-16 13:36:52 -05:00
parent 5f323c5b3a
commit b76e4fe305

View File

@ -459,6 +459,9 @@ struct SemanticValues : protected std::vector<any>
return peg::line_info(ss, s_);
}
// Choice count
size_t choice_count() const { return choice_count_; }
// Choice number (0 based index)
size_t choice() const { return choice_; }
@ -480,7 +483,7 @@ struct SemanticValues : protected std::vector<any>
return this->transform(beg, end, [](const any& v) { return v.get<T>(); });
}
SemanticValues() : s_(nullptr), n_(0), choice_(0) {}
SemanticValues() : s_(nullptr), n_(0), choice_count_(0), choice_(0) {}
using std::vector<any>::iterator;
using std::vector<any>::const_iterator;
@ -512,6 +515,7 @@ private:
const char* s_;
size_t n_;
size_t choice_count_;
size_t choice_;
template <typename F>
@ -532,6 +536,17 @@ private:
}
return r;
}
void reset() {
path = nullptr;
ss = nullptr;
tokens.clear();
s_ = nullptr;
n_ = 0;
choice_count_ = 0;
choice_ = 0;
}
};
/*
@ -846,11 +861,9 @@ public:
if (!sv.empty()) {
sv.clear();
}
sv.reset();
sv.path = path;
sv.ss = s;
sv.s_ = nullptr;
sv.n_ = 0;
sv.tokens.clear();
return sv;
}
@ -996,6 +1009,7 @@ public:
}
sv.s_ = chldsv.c_str();
sv.n_ = chldsv.length();
sv.choice_count_ = opes_.size();
sv.choice_ = id;
sv.tokens.insert(sv.tokens.end(), chldsv.tokens.begin(), chldsv.tokens.end());
@ -2893,12 +2907,18 @@ inline constexpr unsigned int operator "" _(const char* s, size_t) {
template <typename Annotation>
struct AstBase : public Annotation
{
AstBase(const char* a_path, size_t a_line, size_t a_column, const char* a_name, const std::vector<std::shared_ptr<AstBase>>& a_nodes)
AstBase(const char* a_path, size_t a_line, size_t a_column,
const char* a_name, size_t a_choice_count, size_t a_choice,
const std::vector<std::shared_ptr<AstBase>>& a_nodes)
: path(a_path ? a_path : "")
, line(a_line)
, column(a_column)
, name(a_name)
, choice_count(a_choice_count)
, choice(a_choice)
, original_name(a_name)
, original_choice_count(a_choice_count)
, original_choice(a_choice)
#ifndef PEGLIB_NO_CONSTEXPR_SUPPORT
, tag(str2tag(a_name))
, original_tag(tag)
@ -2907,12 +2927,18 @@ struct AstBase : public Annotation
, nodes(a_nodes)
{}
AstBase(const char* a_path, size_t a_line, size_t a_column, const char* a_name, const std::string& a_token)
AstBase(const char* a_path, size_t a_line, size_t a_column,
const char* a_name, size_t a_choice_count, size_t a_choice,
const std::string& a_token)
: path(a_path ? a_path : "")
, line(a_line)
, column(a_column)
, name(a_name)
, choice_count(a_choice_count)
, choice(a_choice)
, original_name(a_name)
, original_choice_count(a_choice_count)
, original_choice(a_choice)
#ifndef PEGLIB_NO_CONSTEXPR_SUPPORT
, tag(str2tag(a_name))
, original_tag(tag)
@ -2921,12 +2947,17 @@ struct AstBase : public Annotation
, token(a_token)
{}
AstBase(const AstBase& ast, const char* a_original_name)
AstBase(const AstBase& ast, const char* a_original_name,
size_t a_original_choice_count, size_t a_original_choise)
: path(ast.path)
, line(ast.line)
, column(ast.column)
, name(ast.name)
, choice_count(ast.choice_count)
, choice(ast.choice)
, original_name(a_original_name)
, original_choice_count(a_original_choice_count)
, original_choice(a_original_choise)
#ifndef PEGLIB_NO_CONSTEXPR_SUPPORT
, tag(ast.tag)
, original_tag(str2tag(a_original_name))
@ -2942,7 +2973,11 @@ struct AstBase : public Annotation
const size_t column;
const std::string name;
const size_t choice_count;
const size_t choice;
const std::string original_name;
const size_t original_choice_count;
const size_t original_choice;
#ifndef PEGLIB_NO_CONSTEXPR_SUPPORT
const unsigned int tag;
const unsigned int original_tag;
@ -2966,11 +3001,12 @@ void ast_to_s_core(
for (auto i = 0; i < level; i++) {
s += " ";
}
std::string name;
if (ast.name == ast.original_name) {
name = ast.name;
} else {
name = ast.original_name + "[" + ast.name + "]";
auto name = ast.original_name;
if (ast.original_choice_count > 0) {
name += "/" + std::to_string(ast.original_choice);
}
if (ast.name != ast.original_name) {
name += "[" + ast.name + "]";
}
if (ast.is_token) {
s += "- " + name + " (" + ast.token + ")\n";
@ -3009,7 +3045,8 @@ struct AstOptimizer
if (opt && original->nodes.size() == 1) {
auto child = optimize(original->nodes[0], parent);
return std::make_shared<T>(*child, original->name.c_str());
return std::make_shared<T>(
*child, original->name.c_str(), original->choice_count, original->choice);
}
auto ast = std::make_shared<T>(*original);
@ -3199,10 +3236,16 @@ public:
auto line = line_info(sv.ss, sv.c_str());
if (rule.is_token()) {
return std::make_shared<T>(sv.path, line.first, line.second, name.c_str(), sv.token());
return std::make_shared<T>(
sv.path, line.first, line.second,
name.c_str(), sv.choice_count(), sv.choice(),
sv.token());
}
auto ast = std::make_shared<T>(sv.path, line.first, line.second, name.c_str(), sv.transform<std::shared_ptr<T>>());
auto ast = std::make_shared<T>(
sv.path, line.first, line.second,
name.c_str(), sv.choice_count(), sv.choice(),
sv.transform<std::shared_ptr<T>>());
for (auto node: ast->nodes) {
node->parent = ast;