This commit is contained in:
yhirose 2018-07-29 13:49:00 -04:00
parent 6584bfa5c6
commit 5445b5c2bb
2 changed files with 45 additions and 1 deletions

View File

@ -1363,6 +1363,7 @@ struct AssignIDToDefinition : public Ope::Visitor
void visit(WeakHolder& ope) override { ope.weak_.lock()->accept(*this); } void visit(WeakHolder& ope) override { ope.weak_.lock()->accept(*this); }
void visit(Holder& ope) override; void visit(Holder& ope) override;
void visit(Reference& ope) override; void visit(Reference& ope) override;
void visit(Whitespace& ope) override { ope.ope_->accept(*this); }
std::unordered_map<void*, size_t> ids; std::unordered_map<void*, size_t> ids;
}; };
@ -1760,12 +1761,18 @@ private:
Definition& operator=(Definition&& rhs); Definition& operator=(Definition&& rhs);
Result parse_core(const char* s, size_t n, SemanticValues& sv, any& dt, const char* path) const { Result parse_core(const char* s, size_t n, SemanticValues& sv, any& dt, const char* path) const {
std::shared_ptr<Ope> ope = holder_;
AssignIDToDefinition vis; AssignIDToDefinition vis;
holder_->accept(vis); holder_->accept(vis);
std::shared_ptr<Ope> ope = holder_;
if (whitespaceOpe) { if (whitespaceOpe) {
ope = std::make_shared<Sequence>(whitespaceOpe, ope); ope = std::make_shared<Sequence>(whitespaceOpe, ope);
whitespaceOpe->accept(vis);
}
if (wordOpe) {
wordOpe->accept(vis);
} }
Context cxt(path, s, n, vis.ids.size(), whitespaceOpe, wordOpe, enablePackratParsing, tracer); 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) { inline void AssignIDToDefinition::visit(Reference& ope) {
if (ope.rule_) { if (ope.rule_) {
for (auto arg: ope.args_) {
arg->accept(*this);
}
ope.rule_->accept(*this); ope.rule_->accept(*this);
} }
} }

View File

@ -701,6 +701,40 @@ TEST_CASE("Definition duplicates test", "[general]")
REQUIRE(!parser); 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]") TEST_CASE("Backreference test", "[backreference]")
{ {
parser parser(R"( parser parser(R"(