Skip to content

Commit 15c19e4

Browse files
committed
1 parent b76e4fe commit 15c19e4

File tree

2 files changed

+34
-4
lines changed

2 files changed

+34
-4
lines changed

peglib.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,7 @@ struct SemanticValues : protected std::vector<any>
510510

511511
private:
512512
friend class Context;
513+
friend class Sequence;
513514
friend class PrioritizedChoice;
514515
friend class Holder;
515516

@@ -948,17 +949,22 @@ class Sequence : public Ope
948949

949950
size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override {
950951
c.trace("Sequence", s, n, sv, dt);
952+
auto& chldsv = c.push();
951953
size_t i = 0;
952954
for (const auto& ope : opes_) {
953955
c.nest_level++;
954956
auto se = make_scope_exit([&]() { c.nest_level--; });
955957
const auto& rule = *ope;
956-
auto len = rule.parse(s + i, n - i, sv, c, dt);
958+
auto len = rule.parse(s + i, n - i, chldsv, c, dt);
957959
if (fail(len)) {
958960
return static_cast<size_t>(-1);
959961
}
960962
i += len;
961963
}
964+
sv.insert(sv.end(), chldsv.begin(), chldsv.end());
965+
sv.s_ = chldsv.c_str();
966+
sv.n_ = chldsv.length();
967+
sv.tokens.insert(sv.tokens.end(), chldsv.tokens.begin(), chldsv.tokens.end());
962968
return i;
963969
}
964970

@@ -1004,9 +1010,7 @@ class PrioritizedChoice : public Ope
10041010
const auto& rule = *ope;
10051011
auto len = rule.parse(s, n, chldsv, c, dt);
10061012
if (success(len)) {
1007-
if (!chldsv.empty()) {
1008-
sv.insert(sv.end(), chldsv.begin(), chldsv.end());
1009-
}
1013+
sv.insert(sv.end(), chldsv.begin(), chldsv.end());
10101014
sv.s_ = chldsv.c_str();
10111015
sv.n_ = chldsv.length();
10121016
sv.choice_count_ = opes_.size();

test/test.cc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,32 @@ TEST_CASE("Definition duplicates test", "[general]")
741741
REQUIRE(!parser);
742742
}
743743

744+
TEST_CASE("Semantic values test", "[general]")
745+
{
746+
parser parser(R"(
747+
term <- ( a b c x )? a b c
748+
a <- 'a'
749+
b <- 'b'
750+
c <- 'c'
751+
x <- 'x'
752+
)");
753+
754+
for (const auto& rule: parser.get_rule_names()){
755+
parser[rule.c_str()] = [rule](const SemanticValues& sv, any&) {
756+
if (rule == "term") {
757+
REQUIRE(sv[0].get<string>() == "a at 0");
758+
REQUIRE(sv[1].get<string>() == "b at 1");
759+
REQUIRE(sv[2].get<string>() == "c at 2");
760+
return string();
761+
} else {
762+
return rule + " at " + to_string(sv.c_str() - sv.ss);
763+
}
764+
};
765+
}
766+
767+
REQUIRE(parser.parse("abc"));
768+
}
769+
744770
TEST_CASE("Packrat parser test with %whitespace%", "[packrat]")
745771
{
746772
peg::parser parser(R"(

0 commit comments

Comments
 (0)