mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2024-12-22 11:55:30 +00:00
Fixed backtracking problem with the prioritized choice.
This commit is contained in:
parent
d386f2f3b9
commit
5a16f53a71
5
peglib.h
5
peglib.h
@ -245,11 +245,16 @@ public:
|
|||||||
PrioritizedChoice(std::vector<std::shared_ptr<Rule>>&& rules) : rules_(std::move(rules)) {}
|
PrioritizedChoice(std::vector<std::shared_ptr<Rule>>&& rules) : rules_(std::move(rules)) {}
|
||||||
|
|
||||||
Match parse(const char* s, size_t l, SemanticValues& sv) const {
|
Match parse(const char* s, size_t l, SemanticValues& sv) const {
|
||||||
|
auto sz = sv.values.size();
|
||||||
for (const auto& rule : rules_) {
|
for (const auto& rule : rules_) {
|
||||||
auto m = rule->parse(s, l, sv);
|
auto m = rule->parse(s, l, sv);
|
||||||
if (m.ret) {
|
if (m.ret) {
|
||||||
return success(m.len);
|
return success(m.len);
|
||||||
}
|
}
|
||||||
|
while (sv.values.size() > sz) {
|
||||||
|
sv.values.pop_back();
|
||||||
|
sv.names.pop_back();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return fail();
|
return fail();
|
||||||
}
|
}
|
||||||
|
34
test/test.cc
34
test/test.cc
@ -5,6 +5,11 @@
|
|||||||
#include <peglib.h>
|
#include <peglib.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
TEST_CASE("Empty syntax test", "[general]")
|
||||||
|
{
|
||||||
|
REQUIRE_THROWS(peglib::make_parser(""));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("String capture test", "[general]")
|
TEST_CASE("String capture test", "[general]")
|
||||||
{
|
{
|
||||||
auto parser = peglib::make_parser(
|
auto parser = peglib::make_parser(
|
||||||
@ -95,6 +100,35 @@ TEST_CASE("Lambda action test", "[general]")
|
|||||||
REQUIRE(ss == "hello");
|
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]")
|
TEST_CASE("Calculator test", "[general]")
|
||||||
{
|
{
|
||||||
// Construct grammer
|
// Construct grammer
|
||||||
|
Loading…
Reference in New Issue
Block a user