mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2024-12-22 20:05:31 +00:00
fix #55
This commit is contained in:
parent
b76e4fe305
commit
15c19e4a0f
12
peglib.h
12
peglib.h
@ -510,6 +510,7 @@ struct SemanticValues : protected std::vector<any>
|
||||
|
||||
private:
|
||||
friend class Context;
|
||||
friend class Sequence;
|
||||
friend class PrioritizedChoice;
|
||||
friend class Holder;
|
||||
|
||||
@ -948,17 +949,22 @@ public:
|
||||
|
||||
size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override {
|
||||
c.trace("Sequence", s, n, sv, dt);
|
||||
auto& chldsv = c.push();
|
||||
size_t i = 0;
|
||||
for (const auto& ope : opes_) {
|
||||
c.nest_level++;
|
||||
auto se = make_scope_exit([&]() { c.nest_level--; });
|
||||
const auto& rule = *ope;
|
||||
auto len = rule.parse(s + i, n - i, sv, c, dt);
|
||||
auto len = rule.parse(s + i, n - i, chldsv, c, dt);
|
||||
if (fail(len)) {
|
||||
return static_cast<size_t>(-1);
|
||||
}
|
||||
i += len;
|
||||
}
|
||||
sv.insert(sv.end(), chldsv.begin(), chldsv.end());
|
||||
sv.s_ = chldsv.c_str();
|
||||
sv.n_ = chldsv.length();
|
||||
sv.tokens.insert(sv.tokens.end(), chldsv.tokens.begin(), chldsv.tokens.end());
|
||||
return i;
|
||||
}
|
||||
|
||||
@ -1004,9 +1010,7 @@ public:
|
||||
const auto& rule = *ope;
|
||||
auto len = rule.parse(s, n, chldsv, c, dt);
|
||||
if (success(len)) {
|
||||
if (!chldsv.empty()) {
|
||||
sv.insert(sv.end(), chldsv.begin(), chldsv.end());
|
||||
}
|
||||
sv.insert(sv.end(), chldsv.begin(), chldsv.end());
|
||||
sv.s_ = chldsv.c_str();
|
||||
sv.n_ = chldsv.length();
|
||||
sv.choice_count_ = opes_.size();
|
||||
|
26
test/test.cc
26
test/test.cc
@ -741,6 +741,32 @@ TEST_CASE("Definition duplicates test", "[general]")
|
||||
REQUIRE(!parser);
|
||||
}
|
||||
|
||||
TEST_CASE("Semantic values test", "[general]")
|
||||
{
|
||||
parser parser(R"(
|
||||
term <- ( a b c x )? a b c
|
||||
a <- 'a'
|
||||
b <- 'b'
|
||||
c <- 'c'
|
||||
x <- 'x'
|
||||
)");
|
||||
|
||||
for (const auto& rule: parser.get_rule_names()){
|
||||
parser[rule.c_str()] = [rule](const SemanticValues& sv, any&) {
|
||||
if (rule == "term") {
|
||||
REQUIRE(sv[0].get<string>() == "a at 0");
|
||||
REQUIRE(sv[1].get<string>() == "b at 1");
|
||||
REQUIRE(sv[2].get<string>() == "c at 2");
|
||||
return string();
|
||||
} else {
|
||||
return rule + " at " + to_string(sv.c_str() - sv.ss);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
REQUIRE(parser.parse("abc"));
|
||||
}
|
||||
|
||||
TEST_CASE("Packrat parser test with %whitespace%", "[packrat]")
|
||||
{
|
||||
peg::parser parser(R"(
|
||||
|
Loading…
Reference in New Issue
Block a user