mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2024-12-23 04:15:31 +00:00
Fix #67
This commit is contained in:
parent
9ee03a9211
commit
3482a08465
42
peglib.h
42
peglib.h
@ -432,6 +432,23 @@ inline std::pair<size_t, size_t> line_info(const char* start, const char* cur) {
|
|||||||
return std::make_pair(no, col);
|
return std::make_pair(no, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* String tag
|
||||||
|
*/
|
||||||
|
#ifndef PEGLIB_NO_CONSTEXPR_SUPPORT
|
||||||
|
inline constexpr unsigned int str2tag(const char* str, int h = 0) {
|
||||||
|
return !str[h] ? 5381 : (str2tag(str, h + 1) * 33) ^ static_cast<unsigned char>(str[h]);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace udl {
|
||||||
|
|
||||||
|
inline constexpr unsigned int operator "" _(const char* s, size_t) {
|
||||||
|
return str2tag(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Semantic values
|
* Semantic values
|
||||||
*/
|
*/
|
||||||
@ -452,6 +469,10 @@ struct SemanticValues : protected std::vector<any>
|
|||||||
// Definition name
|
// Definition name
|
||||||
const std::string& name() const { return name_; }
|
const std::string& name() const { return name_; }
|
||||||
|
|
||||||
|
#ifndef PEGLIB_NO_CONSTEXPR_SUPPORT
|
||||||
|
std::vector<unsigned int> tags;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Line number and column at which the matched string is
|
// Line number and column at which the matched string is
|
||||||
std::pair<size_t, size_t> line_info() const {
|
std::pair<size_t, size_t> line_info() const {
|
||||||
return peg::line_info(ss, s_);
|
return peg::line_info(ss, s_);
|
||||||
@ -860,6 +881,7 @@ public:
|
|||||||
auto& sv = *value_stack[value_stack_size++];
|
auto& sv = *value_stack[value_stack_size++];
|
||||||
if (!sv.empty()) {
|
if (!sv.empty()) {
|
||||||
sv.clear();
|
sv.clear();
|
||||||
|
sv.tags.clear();
|
||||||
}
|
}
|
||||||
sv.reset();
|
sv.reset();
|
||||||
sv.path = path;
|
sv.path = path;
|
||||||
@ -961,6 +983,7 @@ public:
|
|||||||
i += len;
|
i += len;
|
||||||
}
|
}
|
||||||
sv.insert(sv.end(), chldsv.begin(), chldsv.end());
|
sv.insert(sv.end(), chldsv.begin(), chldsv.end());
|
||||||
|
sv.tags.insert(sv.tags.end(), chldsv.tags.begin(), chldsv.tags.end());
|
||||||
sv.s_ = chldsv.c_str();
|
sv.s_ = chldsv.c_str();
|
||||||
sv.n_ = chldsv.length();
|
sv.n_ = chldsv.length();
|
||||||
sv.tokens.insert(sv.tokens.end(), chldsv.tokens.begin(), chldsv.tokens.end());
|
sv.tokens.insert(sv.tokens.end(), chldsv.tokens.begin(), chldsv.tokens.end());
|
||||||
@ -1010,6 +1033,7 @@ public:
|
|||||||
auto len = rule.parse(s, n, chldsv, c, dt);
|
auto len = rule.parse(s, n, chldsv, c, dt);
|
||||||
if (success(len)) {
|
if (success(len)) {
|
||||||
sv.insert(sv.end(), chldsv.begin(), chldsv.end());
|
sv.insert(sv.end(), chldsv.begin(), chldsv.end());
|
||||||
|
sv.tags.insert(sv.tags.end(), chldsv.tags.begin(), chldsv.tags.end());
|
||||||
sv.s_ = chldsv.c_str();
|
sv.s_ = chldsv.c_str();
|
||||||
sv.n_ = chldsv.length();
|
sv.n_ = chldsv.length();
|
||||||
sv.choice_count_ = opes_.size();
|
sv.choice_count_ = opes_.size();
|
||||||
@ -1056,6 +1080,7 @@ public:
|
|||||||
} else {
|
} else {
|
||||||
if (sv.size() != save_sv_size) {
|
if (sv.size() != save_sv_size) {
|
||||||
sv.erase(sv.begin() + static_cast<std::ptrdiff_t>(save_sv_size));
|
sv.erase(sv.begin() + static_cast<std::ptrdiff_t>(save_sv_size));
|
||||||
|
sv.tags.erase(sv.tags.begin() + static_cast<std::ptrdiff_t>(save_sv_size));
|
||||||
}
|
}
|
||||||
if (sv.tokens.size() != save_tok_size) {
|
if (sv.tokens.size() != save_tok_size) {
|
||||||
sv.tokens.erase(sv.tokens.begin() + static_cast<std::ptrdiff_t>(save_tok_size));
|
sv.tokens.erase(sv.tokens.begin() + static_cast<std::ptrdiff_t>(save_tok_size));
|
||||||
@ -1114,6 +1139,7 @@ public:
|
|||||||
} else {
|
} else {
|
||||||
if (sv.size() != save_sv_size) {
|
if (sv.size() != save_sv_size) {
|
||||||
sv.erase(sv.begin() + static_cast<std::ptrdiff_t>(save_sv_size));
|
sv.erase(sv.begin() + static_cast<std::ptrdiff_t>(save_sv_size));
|
||||||
|
sv.tags.erase(sv.tags.begin() + static_cast<std::ptrdiff_t>(save_sv_size));
|
||||||
}
|
}
|
||||||
if (sv.tokens.size() != save_tok_size) {
|
if (sv.tokens.size() != save_tok_size) {
|
||||||
sv.tokens.erase(sv.tokens.begin() + static_cast<std::ptrdiff_t>(save_tok_size));
|
sv.tokens.erase(sv.tokens.begin() + static_cast<std::ptrdiff_t>(save_tok_size));
|
||||||
@ -1155,6 +1181,7 @@ public:
|
|||||||
} else {
|
} else {
|
||||||
if (sv.size() != save_sv_size) {
|
if (sv.size() != save_sv_size) {
|
||||||
sv.erase(sv.begin() + static_cast<std::ptrdiff_t>(save_sv_size));
|
sv.erase(sv.begin() + static_cast<std::ptrdiff_t>(save_sv_size));
|
||||||
|
sv.tags.erase(sv.tags.begin() + static_cast<std::ptrdiff_t>(save_sv_size));
|
||||||
}
|
}
|
||||||
if (sv.tokens.size() != save_tok_size) {
|
if (sv.tokens.size() != save_tok_size) {
|
||||||
sv.tokens.erase(sv.tokens.begin() + static_cast<std::ptrdiff_t>(save_tok_size));
|
sv.tokens.erase(sv.tokens.begin() + static_cast<std::ptrdiff_t>(save_tok_size));
|
||||||
@ -2278,6 +2305,7 @@ inline size_t Holder::parse(const char* s, size_t n, SemanticValues& sv, Context
|
|||||||
if (success(len)) {
|
if (success(len)) {
|
||||||
if (!outer_->ignoreSemanticValue) {
|
if (!outer_->ignoreSemanticValue) {
|
||||||
sv.emplace_back(val);
|
sv.emplace_back(val);
|
||||||
|
sv.tags.emplace_back(str2tag(outer_->name.c_str()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (outer_->error_message) {
|
if (outer_->error_message) {
|
||||||
@ -2957,20 +2985,6 @@ private:
|
|||||||
* AST
|
* AST
|
||||||
*---------------------------------------------------------------------------*/
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
const int AstDefaultTag = -1;
|
|
||||||
|
|
||||||
#ifndef PEGLIB_NO_CONSTEXPR_SUPPORT
|
|
||||||
inline constexpr unsigned int str2tag(const char* str, int h = 0) {
|
|
||||||
return !str[h] ? 5381 : (str2tag(str, h + 1) * 33) ^ static_cast<unsigned char>(str[h]);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace udl {
|
|
||||||
inline constexpr unsigned int operator "" _(const char* s, size_t) {
|
|
||||||
return str2tag(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <typename Annotation>
|
template <typename Annotation>
|
||||||
struct AstBase : public Annotation
|
struct AstBase : public Annotation
|
||||||
{
|
{
|
||||||
|
45
test/test.cc
45
test/test.cc
@ -842,6 +842,51 @@ TEST_CASE("Ordered choice count 2", "[general]")
|
|||||||
parser.parse("b");
|
parser.parse("b");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Semantic value tag", "[general]")
|
||||||
|
{
|
||||||
|
parser parser(R"(
|
||||||
|
S <- A? B* C?
|
||||||
|
A <- 'a'
|
||||||
|
B <- 'b'
|
||||||
|
C <- 'c'
|
||||||
|
)");
|
||||||
|
|
||||||
|
{
|
||||||
|
using namespace udl;
|
||||||
|
parser["S"] = [](const SemanticValues& sv) {
|
||||||
|
REQUIRE(sv.size() == 1);
|
||||||
|
REQUIRE(sv.tags.size() == 1);
|
||||||
|
REQUIRE(sv.tags[0] == "C"_);
|
||||||
|
};
|
||||||
|
auto ret = parser.parse("c");
|
||||||
|
REQUIRE(ret == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
using namespace udl;
|
||||||
|
parser["S"] = [](const SemanticValues& sv) {
|
||||||
|
REQUIRE(sv.size() == 2);
|
||||||
|
REQUIRE(sv.tags.size() == 2);
|
||||||
|
REQUIRE(sv.tags[0] == "B"_);
|
||||||
|
REQUIRE(sv.tags[1] == "B"_);
|
||||||
|
};
|
||||||
|
auto ret = parser.parse("bb");
|
||||||
|
REQUIRE(ret == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
using namespace udl;
|
||||||
|
parser["S"] = [](const SemanticValues& sv) {
|
||||||
|
REQUIRE(sv.size() == 2);
|
||||||
|
REQUIRE(sv.tags.size() == 2);
|
||||||
|
REQUIRE(sv.tags[0] == "A"_);
|
||||||
|
REQUIRE(sv.tags[1] == "C"_);
|
||||||
|
};
|
||||||
|
auto ret = parser.parse("ac");
|
||||||
|
REQUIRE(ret == true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("Packrat parser test with %whitespace%", "[packrat]")
|
TEST_CASE("Packrat parser test with %whitespace%", "[packrat]")
|
||||||
{
|
{
|
||||||
peg::parser parser(R"(
|
peg::parser parser(R"(
|
||||||
|
Loading…
Reference in New Issue
Block a user