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