From be470f93320b6ec98668a65452a5ac4a6b9e8468 Mon Sep 17 00:00:00 2001 From: yhirose Date: Fri, 29 Nov 2019 00:57:45 -0500 Subject: [PATCH] Fix #71 --- peglib.h | 23 ++++++++++++++--------- test/test.cc | 12 ++++++++++++ 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/peglib.h b/peglib.h index e5ecc13..dc97278 100644 --- a/peglib.h +++ b/peglib.h @@ -2486,18 +2486,23 @@ inline void ReferenceChecker::visit(Reference& ope) { } inline void LinkReferences::visit(Reference& ope) { - if (grammar_.count(ope.name_)) { + // Check if the reference is a macro parameter + auto found_param = false; + for (size_t i = 0; i < params_.size(); i++) { + const auto& param = params_[i]; + if (param == ope.name_) { + ope.iarg_ = i; + found_param = true; + break; + } + } + + // Check if the reference is a definition rule + if (!found_param && grammar_.count(ope.name_)) { auto& rule = grammar_.at(ope.name_); ope.rule_ = &rule; - } else { - for (size_t i = 0; i < params_.size(); i++) { - const auto& param = params_[i]; - if (param == ope.name_) { - ope.iarg_ = i; - break; - } - } } + for (auto arg: ope.args_) { arg->accept(*this); } diff --git a/test/test.cc b/test/test.cc index 1a00e03..f926f12 100644 --- a/test/test.cc +++ b/test/test.cc @@ -1453,6 +1453,18 @@ TEST_CASE("Macro token check test", "[macro]") REQUIRE(parser["T"].is_token() == true); } +TEST_CASE("Macro rule-parameter collision", "[macro]") +{ + parser parser(R"( + A <- B(C) + B(D) <- D + C <- 'c' + D <- 'd' + )"); + + REQUIRE(parser.parse("c")); +} + TEST_CASE("Line information test", "[line information]") { parser parser(R"(