mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2024-12-22 11:55:30 +00:00
Simplefiled API.
This commit is contained in:
parent
2aa60699be
commit
42156c35f3
20
README.md
20
README.md
@ -59,8 +59,8 @@ int main(void) {
|
||||
}
|
||||
};
|
||||
|
||||
parser["Number"] = [](const char* s, size_t n) {
|
||||
return stoi(string(s, n), nullptr, 10);
|
||||
parser["Number"] = [](const SemanticValues& sv) {
|
||||
return stoi(string(sv.s, sv.n), nullptr, 10);
|
||||
};
|
||||
|
||||
// (4) Parse
|
||||
@ -73,13 +73,11 @@ int main(void) {
|
||||
}
|
||||
```
|
||||
|
||||
Here is a complete list of available actions:
|
||||
Here are available actions:
|
||||
|
||||
```c++
|
||||
[](const SemanticValues& sv, any& dt)
|
||||
[](const SemanticValues& sv)
|
||||
[](const char* s, size_t n)
|
||||
[]()
|
||||
```
|
||||
|
||||
`const SemanticValues& sv` contains semantic values. `SemanticValues` structure is defined as follows.
|
||||
@ -126,9 +124,9 @@ auto syntax = R"(
|
||||
|
||||
peg pg(syntax);
|
||||
|
||||
pg["TOKEN"] = [](const char* s, size_t n) {
|
||||
pg["TOKEN"] = [](const SemanticValues& sv) {
|
||||
// 'token' doesn't include trailing whitespaces
|
||||
auto token = string(s, n);
|
||||
auto token = string(sv.s, sv.n);
|
||||
};
|
||||
|
||||
auto ret = pg.parse(" token1, token2 ");
|
||||
@ -165,8 +163,8 @@ peglib::peg parser(
|
||||
```c++
|
||||
peglib::peg parser("NUMBER <- [0-9]+");
|
||||
|
||||
parser["NUMBER"] = [](const char* s, size_t n) {
|
||||
auto val = stol(string(s, n), nullptr, 10);
|
||||
parser["NUMBER"] = [](const SemanticValues& sv) {
|
||||
auto val = stol(string(sv.s, sv.n), nullptr, 10);
|
||||
if (val != 100) {
|
||||
throw peglib::parse_error("value error!!");
|
||||
}
|
||||
@ -280,8 +278,8 @@ vector<string> tags;
|
||||
|
||||
Definition ROOT, TAG_NAME, _;
|
||||
ROOT <= seq(_, zom(seq(chr('['), TAG_NAME, chr(']'), _)));
|
||||
TAG_NAME <= oom(seq(npd(chr(']')), dot())), [&](const char* s, size_t n) {
|
||||
tags.push_back(string(s, n));
|
||||
TAG_NAME <= oom(seq(npd(chr(']')), dot())), [&](const SemanticValues& sv) {
|
||||
tags.push_back(string(sv.s, sv.n));
|
||||
};
|
||||
_ <= zom(cls(" \t"));
|
||||
|
||||
|
@ -46,9 +46,9 @@ int main(int argc, const char** argv)
|
||||
|
||||
parser["EXPRESSION"] = reduce;
|
||||
parser["TERM"] = reduce;
|
||||
parser["TERM_OPERATOR"] = [](const char* s, size_t n) { return (char)*s; };
|
||||
parser["FACTOR_OPERATOR"] = [](const char* s, size_t n) { return (char)*s; };
|
||||
parser["NUMBER"] = [](const char* s, size_t n) { return atol(s); };
|
||||
parser["TERM_OPERATOR"] = [](const SemanticValues& sv) { return (char)*sv.s; };
|
||||
parser["FACTOR_OPERATOR"] = [](const SemanticValues& sv) { return (char)*sv.s; };
|
||||
parser["NUMBER"] = [](const SemanticValues& sv) { return atol(sv.s); };
|
||||
|
||||
auto expr = argv[1];
|
||||
long val = 0;
|
||||
|
@ -49,9 +49,9 @@ int main(int argc, const char** argv)
|
||||
EXPRESSION <= seq(TERM, zom(seq(TERM_OPERATOR, TERM))), reduce;
|
||||
TERM <= seq(FACTOR, zom(seq(FACTOR_OPERATOR, FACTOR))), reduce;
|
||||
FACTOR <= cho(NUMBER, seq(chr('('), EXPRESSION, chr(')')));
|
||||
TERM_OPERATOR <= cls("+-"), [](const char* s, size_t n) { return (char)*s; };
|
||||
FACTOR_OPERATOR <= cls("*/"), [](const char* s, size_t n) { return (char)*s; };
|
||||
NUMBER <= oom(cls("0-9")), [](const char* s, size_t n) { return atol(s); };
|
||||
TERM_OPERATOR <= cls("+-"), [](const SemanticValues& sv) { return (char)*sv.s; };
|
||||
FACTOR_OPERATOR <= cls("*/"), [](const SemanticValues& sv) { return (char)*sv.s; };
|
||||
NUMBER <= oom(cls("0-9")), [](const SemanticValues& sv) { return atol(sv.s); };
|
||||
|
||||
auto expr = argv[1];
|
||||
long val = 0;
|
||||
|
40
peglib.h
40
peglib.h
@ -209,7 +209,7 @@ struct SemanticValues : protected std::vector<SemanticValue>
|
||||
auto transform(F f) const -> vector<typename std::remove_const<decltype(f(SemanticValue()))>::type> {
|
||||
vector<typename std::remove_const<decltype(f(SemanticValue()))>::type> r;
|
||||
for (const auto& v: *this) {
|
||||
r.push_back(f(v));
|
||||
r.emplace_back(f(v));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
@ -219,7 +219,7 @@ struct SemanticValues : protected std::vector<SemanticValue>
|
||||
vector<typename std::remove_const<decltype(f(SemanticValue()))>::type> r;
|
||||
end = std::min(end, size());
|
||||
for (size_t i = beg; i < end; i++) {
|
||||
r.push_back(f((*this)[i]));
|
||||
r.emplace_back(f((*this)[i]));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
@ -343,6 +343,7 @@ private:
|
||||
std::function<R (const SemanticValues& sv, any& dt)> fn_;
|
||||
};
|
||||
|
||||
#if 0
|
||||
template <typename R>
|
||||
struct TypeAdaptor_s_l {
|
||||
TypeAdaptor_s_l(std::function<R (const char* s, size_t n)> fn) : fn_(fn) {}
|
||||
@ -360,6 +361,7 @@ private:
|
||||
}
|
||||
std::function<R ()> fn_;
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef std::function<any (const SemanticValues& sv, any& dt)> Fty;
|
||||
|
||||
@ -393,6 +395,7 @@ private:
|
||||
return TypeAdaptor_c<R>(fn);
|
||||
}
|
||||
|
||||
#if 0
|
||||
template<typename F, typename R>
|
||||
Fty make_adaptor(F fn, R (F::*mf)(const char*, size_t) const) {
|
||||
return TypeAdaptor_s_l<R>(fn);
|
||||
@ -422,6 +425,7 @@ private:
|
||||
Fty make_adaptor(F fn, R (*mf)()) {
|
||||
return TypeAdaptor_empty<R>(fn);
|
||||
}
|
||||
#endif
|
||||
|
||||
Fty fn_;
|
||||
};
|
||||
@ -509,7 +513,7 @@ struct Context
|
||||
inline SemanticValues& push() {
|
||||
assert(stack_size <= stack.size());
|
||||
if (stack_size == stack.size()) {
|
||||
stack.push_back(std::make_shared<SemanticValues>());
|
||||
stack.emplace_back(std::make_shared<SemanticValues>());
|
||||
}
|
||||
auto& sv = *stack[stack_size++];
|
||||
if (!sv.empty()) {
|
||||
@ -1671,7 +1675,7 @@ private:
|
||||
data.start = name;
|
||||
}
|
||||
} else {
|
||||
data.duplicates.push_back(std::make_pair(name, sv.s));
|
||||
data.duplicates.emplace_back(name, sv.s);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1681,7 +1685,7 @@ private:
|
||||
} else {
|
||||
std::vector<std::shared_ptr<Ope>> opes;
|
||||
for (auto i = 0u; i < sv.size(); i++) {
|
||||
opes.push_back(sv[i].get<std::shared_ptr<Ope>>());
|
||||
opes.emplace_back(sv[i].get<std::shared_ptr<Ope>>());
|
||||
}
|
||||
const std::shared_ptr<Ope> ope = std::make_shared<PrioritizedChoice>(opes);
|
||||
return ope;
|
||||
@ -1694,7 +1698,7 @@ private:
|
||||
} else {
|
||||
std::vector<std::shared_ptr<Ope>> opes;
|
||||
for (const auto& x: sv) {
|
||||
opes.push_back(x.get<std::shared_ptr<Ope>>());
|
||||
opes.emplace_back(x.get<std::shared_ptr<Ope>>());
|
||||
}
|
||||
const std::shared_ptr<Ope> ope = std::make_shared<Sequence>(opes);
|
||||
return ope;
|
||||
@ -1772,25 +1776,25 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
g["IdentCont"] = [](const char* s, size_t n) {
|
||||
return std::string(s, n);
|
||||
g["IdentCont"] = [](const SemanticValues& sv) {
|
||||
return std::string(sv.s, sv.n);
|
||||
};
|
||||
|
||||
g["Literal"] = [this](const char* s, size_t n) {
|
||||
return lit(resolve_escape_sequence(s, n));
|
||||
g["Literal"] = [this](const SemanticValues& sv) {
|
||||
return lit(resolve_escape_sequence(sv.s, sv.n));
|
||||
};
|
||||
g["Class"] = [this](const char* s, size_t n) {
|
||||
return cls(resolve_escape_sequence(s, n));
|
||||
g["Class"] = [this](const SemanticValues& sv) {
|
||||
return cls(resolve_escape_sequence(sv.s, sv.n));
|
||||
};
|
||||
|
||||
g["AND"] = [](const char* s, size_t n) { return *s; };
|
||||
g["NOT"] = [](const char* s, size_t n) { return *s; };
|
||||
g["QUESTION"] = [](const char* s, size_t n) { return *s; };
|
||||
g["STAR"] = [](const char* s, size_t n) { return *s; };
|
||||
g["PLUS"] = [](const char* s, size_t n) { return *s; };
|
||||
g["AND"] = [](const SemanticValues& sv) { return *sv.s; };
|
||||
g["NOT"] = [](const SemanticValues& sv) { return *sv.s; };
|
||||
g["QUESTION"] = [](const SemanticValues& sv) { return *sv.s; };
|
||||
g["STAR"] = [](const SemanticValues& sv) { return *sv.s; };
|
||||
g["PLUS"] = [](const SemanticValues& sv) { return *sv.s; };
|
||||
|
||||
|
||||
g["DOT"] = []() { return dot(); };
|
||||
g["DOT"] = [](const SemanticValues& sv) { return dot(); };
|
||||
}
|
||||
|
||||
std::shared_ptr<Grammar> perform_core(
|
||||
|
46
test/test.cc
46
test/test.cc
@ -33,8 +33,8 @@ TEST_CASE("String capture test", "[general]")
|
||||
|
||||
std::vector<std::string> tags;
|
||||
|
||||
parser["TAG_NAME"] = [&](const char* s, size_t n) {
|
||||
tags.push_back(std::string(s, n));
|
||||
parser["TAG_NAME"] = [&](const peglib::SemanticValues& sv) {
|
||||
tags.push_back(std::string(sv.s, sv.n));
|
||||
};
|
||||
|
||||
auto ret = parser.parse(" [tag1] [tag:2] [tag-3] ");
|
||||
@ -73,7 +73,7 @@ TEST_CASE("String capture test2", "[general]")
|
||||
Definition ROOT, TAG, TAG_NAME, WS;
|
||||
ROOT <= seq(WS, zom(TAG));
|
||||
TAG <= seq(chr('['), TAG_NAME, chr(']'), WS);
|
||||
TAG_NAME <= oom(seq(npd(chr(']')), dot())), [&](const char* s, size_t n) { tags.push_back(string(s, n)); };
|
||||
TAG_NAME <= oom(seq(npd(chr(']')), dot())), [&](const SemanticValues& sv) { tags.push_back(string(sv.s, sv.n)); };
|
||||
WS <= zom(cls(" \t"));
|
||||
|
||||
auto r = ROOT.parse(" [tag1] [tag:2] [tag-3] ");
|
||||
@ -97,8 +97,8 @@ TEST_CASE("String capture test3", "[general]")
|
||||
|
||||
std::vector<std::string> tags;
|
||||
|
||||
pg["TOKEN"] = [&](const char* s, size_t n) {
|
||||
tags.push_back(std::string(s, n));
|
||||
pg["TOKEN"] = [&](const SemanticValues& sv) {
|
||||
tags.push_back(std::string(sv.s, sv.n));
|
||||
};
|
||||
|
||||
auto ret = pg.parse(" [tag1] [tag:2] [tag-3] ");
|
||||
@ -204,8 +204,8 @@ TEST_CASE("Lambda action test", "[general]")
|
||||
" CHAR <- . ");
|
||||
|
||||
string ss;
|
||||
parser["CHAR"] = [&](const char* s, size_t n) {
|
||||
ss += *s;
|
||||
parser["CHAR"] = [&](const SemanticValues& sv) {
|
||||
ss += *sv.s;
|
||||
};
|
||||
|
||||
bool ret = parser.parse("hello");
|
||||
@ -240,7 +240,7 @@ TEST_CASE("Backtracking test", "[general]")
|
||||
);
|
||||
|
||||
size_t count = 0;
|
||||
parser["HELLO"] = [&](const char* s, size_t n) {
|
||||
parser["HELLO"] = [&](const SemanticValues& sv) {
|
||||
count++;
|
||||
};
|
||||
|
||||
@ -269,8 +269,8 @@ TEST_CASE("mutable lambda test", "[general]")
|
||||
peg pg("ROOT <- 'mutable lambda test'");
|
||||
|
||||
// This test makes sure if the following code can be compiled.
|
||||
pg["TOKEN"] = [=](const char* s, size_t n) mutable {
|
||||
vec.push_back(string(s, n));
|
||||
pg["TOKEN"] = [=](const SemanticValues& sv) mutable {
|
||||
vec.push_back(string(sv.s, sv.n));
|
||||
};
|
||||
}
|
||||
|
||||
@ -302,8 +302,8 @@ TEST_CASE("Simple calculator test", "[general]")
|
||||
}
|
||||
};
|
||||
|
||||
parser["Number"] = [](const char* s, size_t n) {
|
||||
return atoi(s);
|
||||
parser["Number"] = [](const SemanticValues& sv) {
|
||||
return atoi(sv.s);
|
||||
};
|
||||
|
||||
int val;
|
||||
@ -341,9 +341,9 @@ TEST_CASE("Calculator test", "[general]")
|
||||
|
||||
EXPRESSION = reduce;
|
||||
TERM = reduce;
|
||||
TERM_OPERATOR = [](const char* s, size_t n) { return *s; };
|
||||
FACTOR_OPERATOR = [](const char* s, size_t n) { return *s; };
|
||||
NUMBER = [&](const char* s, size_t n) { return stol(string(s, n), nullptr, 10); };
|
||||
TERM_OPERATOR = [](const SemanticValues& sv) { return *sv.s; };
|
||||
FACTOR_OPERATOR = [](const SemanticValues& sv) { return *sv.s; };
|
||||
NUMBER = [](const SemanticValues& sv) { return stol(string(sv.s, sv.n), nullptr, 10); };
|
||||
|
||||
// Parse
|
||||
long val;
|
||||
@ -387,9 +387,9 @@ TEST_CASE("Calculator test2", "[general]")
|
||||
|
||||
g["EXPRESSION"] = reduce;
|
||||
g["TERM"] = reduce;
|
||||
g["TERM_OPERATOR"] = [](const char* s, size_t n) { return *s; };
|
||||
g["FACTOR_OPERATOR"] = [](const char* s, size_t n) { return *s; };
|
||||
g["NUMBER"] = [](const char* s, size_t n) { return stol(string(s, n), nullptr, 10); };
|
||||
g["TERM_OPERATOR"] = [](const SemanticValues& sv) { return *sv.s; };
|
||||
g["FACTOR_OPERATOR"] = [](const SemanticValues& sv) { return *sv.s; };
|
||||
g["NUMBER"] = [](const SemanticValues& sv) { return stol(string(sv.s, sv.n), nullptr, 10); };
|
||||
|
||||
// Parse
|
||||
long val;
|
||||
@ -429,9 +429,9 @@ TEST_CASE("Calculator test3", "[general]")
|
||||
// Setup actions
|
||||
parser["EXPRESSION"] = reduce;
|
||||
parser["TERM"] = reduce;
|
||||
parser["TERM_OPERATOR"] = [](const char* s, size_t n) { return (char)*s; };
|
||||
parser["FACTOR_OPERATOR"] = [](const char* s, size_t n) { return (char)*s; };
|
||||
parser["NUMBER"] = [](const char* s, size_t n) { return stol(string(s, n), nullptr, 10); };
|
||||
parser["TERM_OPERATOR"] = [](const SemanticValues& sv) { return (char)*sv.s; };
|
||||
parser["FACTOR_OPERATOR"] = [](const SemanticValues& sv) { return (char)*sv.s; };
|
||||
parser["NUMBER"] = [](const SemanticValues& sv) { return stol(string(sv.s, sv.n), nullptr, 10); };
|
||||
|
||||
// Parse
|
||||
long val;
|
||||
@ -621,8 +621,8 @@ TEST_CASE("Semantic predicate test", "[predicate]")
|
||||
{
|
||||
peg parser("NUMBER <- [0-9]+");
|
||||
|
||||
parser["NUMBER"] = [](const char* s, size_t n) {
|
||||
auto val = stol(string(s, n), nullptr, 10);
|
||||
parser["NUMBER"] = [](const SemanticValues& sv) {
|
||||
auto val = stol(string(sv.s, sv.n), nullptr, 10);
|
||||
if (val != 100) {
|
||||
throw parse_error("value error!!");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user