mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2024-12-22 11:55:30 +00:00
Fix #109
This commit is contained in:
parent
f9e0d252d9
commit
072cdb6d23
15
peglib.h
15
peglib.h
@ -840,6 +840,8 @@ public:
|
||||
|
||||
std::vector<std::shared_ptr<SemanticValues>> value_stack;
|
||||
size_t value_stack_size = 0;
|
||||
|
||||
std::vector<Definition*> rule_stack;
|
||||
std::vector<std::vector<std::shared_ptr<Ope>>> args_stack;
|
||||
|
||||
bool in_token = false;
|
||||
@ -2475,7 +2477,12 @@ inline size_t Holder::parse_core(const char *s, size_t n, SemanticValues &sv,
|
||||
|
||||
// Macro reference
|
||||
// TODO: need packrat support
|
||||
if (outer_->is_macro) { return ope_->parse(s, n, sv, c, dt); }
|
||||
if (outer_->is_macro) {
|
||||
c.rule_stack.push_back(outer_);
|
||||
auto len = ope_->parse(s, n, sv, c, dt);
|
||||
c.rule_stack.pop_back();
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t len;
|
||||
any val;
|
||||
@ -2491,7 +2498,9 @@ inline size_t Holder::parse_core(const char *s, size_t n, SemanticValues &sv,
|
||||
|
||||
auto &chldsv = c.push();
|
||||
|
||||
c.rule_stack.push_back(outer_);
|
||||
len = ope_->parse(s, n, chldsv, c, dt);
|
||||
c.rule_stack.pop_back();
|
||||
|
||||
// Invoke action
|
||||
if (success(len)) {
|
||||
@ -2556,7 +2565,7 @@ inline size_t Reference::parse_core(const char *s, size_t n, SemanticValues &sv,
|
||||
// Reference rule
|
||||
if (rule_->is_macro) {
|
||||
// Macro
|
||||
FindReference vis(c.top_args(), rule_->params);
|
||||
FindReference vis(c.top_args(), c.rule_stack.back()->params);
|
||||
|
||||
// Collect arguments
|
||||
std::vector<std::shared_ptr<Ope>> args;
|
||||
@ -2571,6 +2580,8 @@ inline size_t Reference::parse_core(const char *s, size_t n, SemanticValues &sv,
|
||||
return ope->parse(s, n, sv, c, dt);
|
||||
} else {
|
||||
// Definition
|
||||
c.push_args(std::vector<std::shared_ptr<Ope>>());
|
||||
auto se = make_scope_exit([&]() { c.pop_args(); });
|
||||
auto ope = get_core_operator();
|
||||
return ope->parse(s, n, sv, c, dt);
|
||||
}
|
||||
|
@ -903,8 +903,7 @@ TEST_CASE("Macro token check test", "[macro]")
|
||||
REQUIRE(parser["T"].is_token() == true);
|
||||
}
|
||||
|
||||
TEST_CASE("Macro rule-parameter collision", "[macro]")
|
||||
{
|
||||
TEST_CASE("Macro passes an arg to another macro", "[macro]") {
|
||||
parser parser(R"(
|
||||
A <- B(C)
|
||||
B(D) <- D
|
||||
@ -915,8 +914,29 @@ TEST_CASE("Macro rule-parameter collision", "[macro]")
|
||||
REQUIRE(parser.parse("c"));
|
||||
}
|
||||
|
||||
TEST_CASE("Line information test", "[line information]")
|
||||
TEST_CASE("Nested macro call", "[macro]") {
|
||||
parser parser(R"(
|
||||
A <- B(T)
|
||||
B(X) <- C(X)
|
||||
C(Y) <- Y
|
||||
T <- 'val'
|
||||
)");
|
||||
|
||||
REQUIRE(parser.parse("val"));
|
||||
}
|
||||
|
||||
TEST_CASE("Nested macro call2", "[macro]")
|
||||
{
|
||||
parser parser(R"(
|
||||
START <- A('TestVal1', 'TestVal2')+
|
||||
A(Aarg1, Aarg2) <- B(Aarg1) '#End'
|
||||
B(Barg1) <- '#' Barg1
|
||||
)");
|
||||
|
||||
REQUIRE(parser.parse("#TestVal1#End"));
|
||||
}
|
||||
|
||||
TEST_CASE("Line information test", "[line information]") {
|
||||
parser parser(R"(
|
||||
S <- _ (WORD _)+
|
||||
WORD <- [A-Za-z]+
|
||||
|
Loading…
Reference in New Issue
Block a user