diff --git a/peglib.h b/peglib.h index 4560f1e..7eb9b68 100644 --- a/peglib.h +++ b/peglib.h @@ -1363,6 +1363,7 @@ struct AssignIDToDefinition : public Ope::Visitor void visit(WeakHolder& ope) override { ope.weak_.lock()->accept(*this); } void visit(Holder& ope) override; void visit(Reference& ope) override; + void visit(Whitespace& ope) override { ope.ope_->accept(*this); } std::unordered_map ids; }; @@ -1760,12 +1761,18 @@ private: Definition& operator=(Definition&& rhs); Result parse_core(const char* s, size_t n, SemanticValues& sv, any& dt, const char* path) const { + std::shared_ptr ope = holder_; + AssignIDToDefinition vis; holder_->accept(vis); - std::shared_ptr ope = holder_; if (whitespaceOpe) { ope = std::make_shared(whitespaceOpe, ope); + whitespaceOpe->accept(vis); + } + + if (wordOpe) { + wordOpe->accept(vis); } Context cxt(path, s, n, vis.ids.size(), whitespaceOpe, wordOpe, enablePackratParsing, tracer); @@ -2022,6 +2029,9 @@ inline void AssignIDToDefinition::visit(Holder& ope) { inline void AssignIDToDefinition::visit(Reference& ope) { if (ope.rule_) { + for (auto arg: ope.args_) { + arg->accept(*this); + } ope.rule_->accept(*this); } } diff --git a/test/test.cc b/test/test.cc index 86a853f..684d029 100644 --- a/test/test.cc +++ b/test/test.cc @@ -701,6 +701,40 @@ TEST_CASE("Definition duplicates test", "[general]") REQUIRE(!parser); } +TEST_CASE("Packrat parser test with %whitespace%", "[packrat]") +{ + peg::parser parser(R"( + ROOT <- 'a' + %whitespace <- SPACE* + SPACE <- ' ' + )"); + + parser.enable_packrat_parsing(); + + auto ret = parser.parse("a"); + REQUIRE(ret == true); +} + +TEST_CASE("Packrat parser test with macro", "[packrat]") +{ + parser parser(R"( + EXPRESSION <- _ LIST(TERM, TERM_OPERATOR) + TERM <- LIST(FACTOR, FACTOR_OPERATOR) + FACTOR <- NUMBER / T('(') EXPRESSION T(')') + TERM_OPERATOR <- T([-+]) + FACTOR_OPERATOR <- T([/*]) + NUMBER <- T([0-9]+) + ~_ <- [ \t]* + LIST(I, D) <- I (D I)* + T(S) <- < S > _ + )"); + + parser.enable_packrat_parsing(); + + auto ret = parser.parse(" 1 + 2 * 3 * (4 - 5 + 6) / 7 - 8 "); + REQUIRE(ret == true); +} + TEST_CASE("Backreference test", "[backreference]") { parser parser(R"(