This commit is contained in:
yhirose 2022-07-07 15:59:03 -04:00
parent 738be51919
commit 0795e26aaa
2 changed files with 32 additions and 0 deletions

View File

@ -768,9 +768,11 @@ public:
std::vector<bool> cut_stack;
#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT
std::vector<std::map<std::string, std::unordered_set<std::string>>>
symbol_tables_stack;
size_t symbol_tables_stack_size = 0;
#endif
const size_t def_count;
const bool enablePackratParsing;
@ -802,7 +804,9 @@ public:
push_args({});
push_capture_scope();
#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT
push_symbol_tables();
#endif
}
~Context() {
@ -812,8 +816,10 @@ public:
assert(!capture_scope_stack_size);
assert(cut_stack.empty());
#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT
pop_symbol_tables();
assert(!symbol_tables_stack_size);
#endif
}
Context(const Context &) = delete;
@ -854,14 +860,18 @@ public:
SemanticValues &push() {
push_capture_scope();
#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT
push_symbol_tables();
#endif
return push_semantic_values_scope();
}
void pop() {
pop_capture_scope();
pop_semantic_values_scope();
#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT
pop_symbol_tables();
#endif
}
// Semantic values
@ -924,6 +934,7 @@ public:
}
}
#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT
// Symbol tables
void push_symbol_tables() {
assert(symbol_tables_stack_size <= symbol_tables_stack.size());
@ -968,6 +979,7 @@ public:
}
return false;
}
#endif
// Error
void set_error_pos(const char *a_s, const char *literal = nullptr);
@ -1060,7 +1072,9 @@ public:
vs.choice_count_ = opes_.size();
vs.choice_ = id;
c.shift_capture_values();
#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT
c.shift_symbol_tables();
#endif
break;
} else if (!c.cut_stack.empty() && c.cut_stack.back()) {
break;
@ -1100,7 +1114,9 @@ public:
if (success(len)) {
vs.append(chvs);
c.shift_capture_values();
#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT
c.shift_symbol_tables();
#endif
} else {
return len;
}
@ -1117,7 +1133,9 @@ public:
if (success(len)) {
vs.append(chvs);
c.shift_capture_values();
#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT
c.shift_symbol_tables();
#endif
} else {
break;
}
@ -2398,9 +2416,11 @@ public:
bool eoi_check = true;
#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT
bool declare_symbol = false;
bool check_symbol = false;
std::string symbol_table_name;
#endif
private:
friend class Reference;
@ -2775,6 +2795,7 @@ inline size_t Holder::parse_core(const char *s, size_t n, SemanticValues &vs,
c.error_info.message = msg;
}
len = static_cast<size_t>(-1);
#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT
} else if (outer_->declare_symbol) {
assert(outer_->is_token());
auto symbol = chvs.token_to_string();
@ -2791,6 +2812,7 @@ inline size_t Holder::parse_core(const char *s, size_t n, SemanticValues &vs,
msg = "'" + symbol + "' doesn't exist.";
len = static_cast<size_t>(-1);
}
#endif
}
if (success(len)) {
@ -3443,8 +3465,10 @@ private:
g["EndBlacket"]);
g["InstructionItem"] <= cho(g["PrecedenceClimbing"], g["ErrorMessage"],
g["NoAstOpt"]
#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT
,
g["DeclareSymbol"], g["CheckSymbol"]
#endif
);
~g["InstructionItemSeparator"] <= seq(chr(';'), g["Spacing"]);
@ -3478,11 +3502,13 @@ private:
// No Ast node optimazation instruction
g["NoAstOpt"] <= seq(lit("no_ast_opt"), g["SpacesZom"]);
#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT
// Symbol table instruction
g["DeclareSymbol"] <= seq(lit("declare_symbol"), g["SpacesZom"],
g["Identifier"], g["SpacesZom"]);
g["CheckSymbol"] <= seq(lit("check_symbol"), g["SpacesZom"],
g["Identifier"], g["SpacesZom"]);
#endif
// Set definition names
for (auto &x : g) {
@ -3886,6 +3912,7 @@ private:
return instruction;
};
#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT
g["DeclareSymbol"] = [](const SemanticValues &vs) {
Instruction instruction;
instruction.type = "declare_symbol";
@ -3901,6 +3928,7 @@ private:
instruction.sv = vs.sv();
return instruction;
};
#endif
g["Instruction"] = [](const SemanticValues &vs) {
return vs.transform<Instruction>();
@ -4152,12 +4180,14 @@ private:
rule.error_message = std::any_cast<std::string>(instruction.data);
} else if (instruction.type == "no_ast_opt") {
rule.no_ast_opt = true;
#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT
} else if (instruction.type == "declare_symbol") {
rule.declare_symbol = true;
rule.symbol_table_name = std::any_cast<std::string>(instruction.data);
} else if (instruction.type == "check_symbol") {
rule.check_symbol = true;
rule.symbol_table_name = std::any_cast<std::string>(instruction.data);
#endif
}
}
}

View File

@ -861,6 +861,7 @@ TEST(PredicateTest, Semantic_predicate_test) {
EXPECT_FALSE(parser.parse("200", val));
}
#ifdef CPPPEGLIB_SYMBOL_TABLE_SUPPORT
TEST(SymbolTableTest, symbol_instruction_test) {
parser parser(R"(S <- (Decl / Ref)*
Decl <- 'decl' symbol
@ -1054,6 +1055,7 @@ decl aaa
EXPECT_FALSE(parser.parse(source, ast));
}
}
#endif
TEST(UnicodeTest, Japanese_character) {
peg::parser parser(u8R"(