Simplefiled API.

This commit is contained in:
yhirose 2015-06-16 00:25:01 -04:00
parent 2aa60699be
commit 42156c35f3
5 changed files with 60 additions and 58 deletions

View File

@ -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"));

View File

@ -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;

View File

@ -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;

View File

@ -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(

View File

@ -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!!");
} }