Fixed backtracking problem with the prioritized choice.

This commit is contained in:
yhirose 2015-02-09 20:13:46 -05:00
parent d386f2f3b9
commit 5a16f53a71
2 changed files with 39 additions and 0 deletions

View File

@ -245,11 +245,16 @@ public:
PrioritizedChoice(std::vector<std::shared_ptr<Rule>>&& rules) : rules_(std::move(rules)) {}
Match parse(const char* s, size_t l, SemanticValues& sv) const {
auto sz = sv.values.size();
for (const auto& rule : rules_) {
auto m = rule->parse(s, l, sv);
if (m.ret) {
return success(m.len);
}
while (sv.values.size() > sz) {
sv.values.pop_back();
sv.names.pop_back();
}
}
return fail();
}

View File

@ -5,6 +5,11 @@
#include <peglib.h>
#include <iostream>
TEST_CASE("Empty syntax test", "[general]")
{
REQUIRE_THROWS(peglib::make_parser(""));
}
TEST_CASE("String capture test", "[general]")
{
auto parser = peglib::make_parser(
@ -95,6 +100,35 @@ TEST_CASE("Lambda action test", "[general]")
REQUIRE(ss == "hello");
}
TEST_CASE("Simple calculator test", "[general]")
{
auto syntax =
" Additive <- Multitive '+' Additive / Multitive "
" Multitive <- Primary '*' Multitive / Primary "
" Primary <- '(' Additive ')' / Number "
" Number <- [0-9]+ ";
auto parser = make_parser(syntax);
parser["Additive"] = [](const vector<Any>& v) {
return v.size() == 1 ? v[0] : v[0].get<int>() + v[1].get<int>();
};
parser["Multitive"] = [](const vector<Any>& v) {
return v.size() == 1 ? v[0] : v[0].get<int>() * v[1].get<int>();
};
parser["Primary"] = [](const vector<Any>& v) {
return v.size() == 1 ? v[0] : v[1];
};
parser["Number"] = [](const char* s, size_t l) {
return atoi(s);
};
int val;
parser.parse("1+2*3", val);
REQUIRE(val == 7);
}
TEST_CASE("Calculator test", "[general]")
{
// Construct grammer