mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2024-12-22 11:55:30 +00:00
Resolve #233
This commit is contained in:
parent
738be51919
commit
0795e26aaa
30
peglib.h
30
peglib.h
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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"(
|
||||
|
Loading…
Reference in New Issue
Block a user