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