From 42156c35f36efcf247d1138fbddce2653c3b0f1c Mon Sep 17 00:00:00 2001 From: yhirose Date: Tue, 16 Jun 2015 00:25:01 -0400 Subject: [PATCH] Simplefiled API. --- README.md | 20 +++++++++----------- example/calc.cc | 6 +++--- example/calc2.cc | 6 +++--- peglib.h | 40 ++++++++++++++++++++++------------------ test/test.cc | 46 +++++++++++++++++++++++----------------------- 5 files changed, 60 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index e7c483f..626cb02 100644 --- a/README.md +++ b/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 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")); diff --git a/example/calc.cc b/example/calc.cc index 1d4596b..f7d8459 100644 --- a/example/calc.cc +++ b/example/calc.cc @@ -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; diff --git a/example/calc2.cc b/example/calc2.cc index 8f288a2..3b8ee45 100644 --- a/example/calc2.cc +++ b/example/calc2.cc @@ -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; diff --git a/peglib.h b/peglib.h index 1947cda..9630188 100644 --- a/peglib.h +++ b/peglib.h @@ -209,7 +209,7 @@ struct SemanticValues : protected std::vector auto transform(F f) const -> vector::type> { vector::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 vector::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 fn_; }; +#if 0 template struct TypeAdaptor_s_l { TypeAdaptor_s_l(std::function fn) : fn_(fn) {} @@ -360,6 +361,7 @@ private: } std::function fn_; }; +#endif typedef std::function Fty; @@ -393,6 +395,7 @@ private: return TypeAdaptor_c(fn); } +#if 0 template Fty make_adaptor(F fn, R (F::*mf)(const char*, size_t) const) { return TypeAdaptor_s_l(fn); @@ -422,6 +425,7 @@ private: Fty make_adaptor(F fn, R (*mf)()) { return TypeAdaptor_empty(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()); + stack.emplace_back(std::make_shared()); } 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> opes; for (auto i = 0u; i < sv.size(); i++) { - opes.push_back(sv[i].get>()); + opes.emplace_back(sv[i].get>()); } const std::shared_ptr ope = std::make_shared(opes); return ope; @@ -1694,7 +1698,7 @@ private: } else { std::vector> opes; for (const auto& x: sv) { - opes.push_back(x.get>()); + opes.emplace_back(x.get>()); } const std::shared_ptr ope = std::make_shared(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 perform_core( diff --git a/test/test.cc b/test/test.cc index 5e166b2..dd51b5d 100644 --- a/test/test.cc +++ b/test/test.cc @@ -33,8 +33,8 @@ TEST_CASE("String capture test", "[general]") std::vector 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 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!!"); }