mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2024-12-22 20:05:31 +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;
|
std::vector<std::shared_ptr<SemanticValues>> value_stack;
|
||||||
size_t value_stack_size = 0;
|
size_t value_stack_size = 0;
|
||||||
|
|
||||||
|
std::vector<Definition*> rule_stack;
|
||||||
std::vector<std::vector<std::shared_ptr<Ope>>> args_stack;
|
std::vector<std::vector<std::shared_ptr<Ope>>> args_stack;
|
||||||
|
|
||||||
bool in_token = false;
|
bool in_token = false;
|
||||||
@ -2475,7 +2477,12 @@ inline size_t Holder::parse_core(const char *s, size_t n, SemanticValues &sv,
|
|||||||
|
|
||||||
// Macro reference
|
// Macro reference
|
||||||
// TODO: need packrat support
|
// 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;
|
size_t len;
|
||||||
any val;
|
any val;
|
||||||
@ -2491,7 +2498,9 @@ inline size_t Holder::parse_core(const char *s, size_t n, SemanticValues &sv,
|
|||||||
|
|
||||||
auto &chldsv = c.push();
|
auto &chldsv = c.push();
|
||||||
|
|
||||||
|
c.rule_stack.push_back(outer_);
|
||||||
len = ope_->parse(s, n, chldsv, c, dt);
|
len = ope_->parse(s, n, chldsv, c, dt);
|
||||||
|
c.rule_stack.pop_back();
|
||||||
|
|
||||||
// Invoke action
|
// Invoke action
|
||||||
if (success(len)) {
|
if (success(len)) {
|
||||||
@ -2556,7 +2565,7 @@ inline size_t Reference::parse_core(const char *s, size_t n, SemanticValues &sv,
|
|||||||
// Reference rule
|
// Reference rule
|
||||||
if (rule_->is_macro) {
|
if (rule_->is_macro) {
|
||||||
// Macro
|
// Macro
|
||||||
FindReference vis(c.top_args(), rule_->params);
|
FindReference vis(c.top_args(), c.rule_stack.back()->params);
|
||||||
|
|
||||||
// Collect arguments
|
// Collect arguments
|
||||||
std::vector<std::shared_ptr<Ope>> args;
|
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);
|
return ope->parse(s, n, sv, c, dt);
|
||||||
} else {
|
} else {
|
||||||
// Definition
|
// Definition
|
||||||
|
c.push_args(std::vector<std::shared_ptr<Ope>>());
|
||||||
|
auto se = make_scope_exit([&]() { c.pop_args(); });
|
||||||
auto ope = get_core_operator();
|
auto ope = get_core_operator();
|
||||||
return ope->parse(s, n, sv, c, dt);
|
return ope->parse(s, n, sv, c, dt);
|
||||||
}
|
}
|
||||||
|
@ -903,20 +903,40 @@ TEST_CASE("Macro token check test", "[macro]")
|
|||||||
REQUIRE(parser["T"].is_token() == true);
|
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"(
|
||||||
parser parser(R"(
|
|
||||||
A <- B(C)
|
A <- B(C)
|
||||||
B(D) <- D
|
B(D) <- D
|
||||||
C <- 'c'
|
C <- 'c'
|
||||||
D <- 'd'
|
D <- 'd'
|
||||||
)");
|
)");
|
||||||
|
|
||||||
REQUIRE(parser.parse("c"));
|
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"(
|
parser parser(R"(
|
||||||
S <- _ (WORD _)+
|
S <- _ (WORD _)+
|
||||||
WORD <- [A-Za-z]+
|
WORD <- [A-Za-z]+
|
||||||
|
Loading…
Reference in New Issue
Block a user