Added 'anchor' support. Removed implecit cast operators from 'any'.

This commit is contained in:
yhirose 2015-02-15 20:11:02 -05:00
parent 81ca85cba5
commit d2ad29359e
3 changed files with 62 additions and 42 deletions

View File

@ -84,12 +84,32 @@ Here is a complete list of available actions:
`any& c` is a context data which can be used by the user for whatever purposes. `any& c` is a context data which can be used by the user for whatever purposes.
In the following example, `<` and ` >` are the *capture* operators. Each capture operator creates a semantic value that contains `const char*` of the position. It could be useful to eliminate unnecessary characters.
```c++
auto syntax = R"(
ROOT <- _ TOKEN (',' _ TOKEN)*
TOKEN <- < [a-z0-9]+ > _
_ <- [ \t\r\n]*
)";
peg pg(syntax);
pg["TOKEN"] = [](const char* s, size_t l, const vector<any>& v) {
auto b = v[0].get<const char*>(); // '<'
auto e = v[1].get<const char*>(); // '>'
auto token = string(b, e - b); // 'token' doesn't include trailing whitespaces
};
auto ret = pg.parse(" token1, token2 ");
```
Simple interface Simple interface
---------------- ----------------
*cpp-peglib* provides std::regex-like simple interface for trivial tasks. *cpp-peglib* provides std::regex-like simple interface for trivial tasks.
In the following example, `< ... >` means the *capture* operator. `peglib::peg_match` tries to capture strings in the `< ... >` operator and store them into `peglib::match` object. `peglib::peg_match` tries to capture strings in the `< ... >` operator and store them into `peglib::match` object.
```c++ ```c++
peglib::match m; peglib::match m;

View File

@ -122,28 +122,6 @@ public:
return *this; return *this;
} }
operator bool() const { return get<bool>(); }
operator char() const { return get<char>(); }
operator wchar_t() const { return get<wchar_t>(); }
operator unsigned char() const { return get<unsigned char>(); }
operator int() const { return get<int>(); }
operator unsigned int() const { return get<unsigned int>(); }
operator short() const { return get<short>(); }
operator unsigned short() const { return get<unsigned short>(); }
operator long() const { return get<long>(); }
operator unsigned long() const { return get<unsigned long>(); }
operator long long() const { return get<long long>(); }
operator unsigned long long() const { return get<unsigned long long>(); }
operator float() const { return get<float>(); }
operator double() const { return get<double>(); }
operator const std::string&() const { return get<std::string>(); }
#if defined(_MSC_VER) && _MSC_VER < 1900 // Less than Visual Studio 2015
#else
operator char16_t() const { return get<char16_t>(); }
operator char32_t() const { return get<char32_t>(); }
#endif
private: private:
struct placeholder { struct placeholder {
virtual ~placeholder() {}; virtual ~placeholder() {};
@ -693,6 +671,15 @@ private:
size_t capture_id; size_t capture_id;
}; };
class Anchor : public Ope
{
public:
Result parse(const char* s, size_t l, Values& v, any& c) const {
return success(0);
}
};
class WeakHolder : public Ope class WeakHolder : public Ope
{ {
public: public:
@ -929,6 +916,10 @@ inline std::shared_ptr<Ope> cap(const std::shared_ptr<Ope>& ope, MatchAction ma)
return std::make_shared<Capture>(ope, ma, (size_t)-1); return std::make_shared<Capture>(ope, ma, (size_t)-1);
} }
inline std::shared_ptr<Ope> anc() {
return std::make_shared<Anchor>();
}
inline std::shared_ptr<Ope> ref(const std::map<std::string, Definition>& grammar, const std::string& name) { inline std::shared_ptr<Ope> ref(const std::map<std::string, Definition>& grammar, const std::string& name) {
return std::make_shared<DefinitionReference>(grammar, name); return std::make_shared<DefinitionReference>(grammar, name);
} }
@ -1132,46 +1123,50 @@ private:
}, },
[&](const char* s, size_t l, const std::vector<any>& v, any& c) { [&](const char* s, size_t l, const std::vector<any>& v, any& c) {
Context& cxt = *c.get<Context*>(); Context& cxt = *c.get<Context*>();
cxt.references[v[0]] = s; const auto& ident = v[0].get<std::string>();
return ref(*cxt.grammar, v[0]); cxt.references[ident] = s; // for error handling
return ref(*cxt.grammar, ident);
}, },
[&](const std::vector<any>& v) { [&](const std::vector<any>& v) {
return v[1]; return v[1];
}, },
// Capture // Capture
[&](const std::vector<any>& v, any& c) { [&](const char* s, size_t l, const std::vector<any>& v, any& c) {
Context& cxt = *c.get<Context*>(); Context& cxt = *c.get<Context*>();
auto ope = v[1].get<std::shared_ptr<Ope>>(); auto ope = v[1].get<std::shared_ptr<Ope>>();
return cap(ope, cxt.match_action, ++cxt.capture_count); return seq(
ref(*cxt.grammar, "%ANCHOR%"),
cap(ope, cxt.match_action, ++cxt.capture_count),
ref(*cxt.grammar, "%ANCHOR%"));
} }
}; };
g["IdentCont"] = [](const char*s, size_t l) { g["IdentCont"] = [](const char* s, size_t l) {
return std::string(s, l); return std::string(s, l);
}; };
g["Literal"] = [](const std::vector<any>& v) { g["Literal"] = [](const std::vector<any>& v) {
return lit(v[0]); return lit(v[0].get<std::string>());
}; };
g["SQCont"] = [this](const char*s, size_t l) { g["SQCont"] = [this](const char* s, size_t l) {
return resolve_escape_sequence(s, l); return resolve_escape_sequence(s, l);
}; };
g["DQCont"] = [this](const char*s, size_t l) { g["DQCont"] = [this](const char* s, size_t l) {
return resolve_escape_sequence(s, l); return resolve_escape_sequence(s, l);
}; };
g["Class"] = [](const std::vector<any>& v) { g["Class"] = [](const std::vector<any>& v) {
return cls(v[0]); return cls(v[0].get<std::string>());
}; };
g["ClassCont"] = [this](const char*s, size_t l) { g["ClassCont"] = [this](const char* s, size_t l) {
return resolve_escape_sequence(s, l); return resolve_escape_sequence(s, l);
}; };
g["AND"] = [](const char*s, size_t l) { return *s; }; g["AND"] = [](const char* s, size_t l) { return *s; };
g["NOT"] = [](const char*s, size_t l) { return *s; }; g["NOT"] = [](const char* s, size_t l) { return *s; };
g["QUESTION"] = [](const char*s, size_t l) { return *s; }; g["QUESTION"] = [](const char* s, size_t l) { return *s; };
g["STAR"] = [](const char*s, size_t l) { return *s; }; g["STAR"] = [](const char* s, size_t l) { return *s; };
g["PLUS"] = [](const char*s, size_t l) { return *s; }; g["PLUS"] = [](const char* s, size_t l) { return *s; };
g["DOT"] = []() { g["DOT"] = []() {
return dot(); return dot();
@ -1194,10 +1189,12 @@ private:
return nullptr; return nullptr;
} }
auto& grammar = *cxt.grammar;
for (const auto& x : cxt.references) { for (const auto& x : cxt.references) {
const auto& name = x.first; const auto& name = x.first;
auto ptr = x.second; auto ptr = x.second;
if (cxt.grammar->find(name) == cxt.grammar->end()) { if (grammar.find(name) == grammar.end()) {
if (log) { if (log) {
auto line = line_info(s, ptr); auto line = line_info(s, ptr);
log(line.first, line.second, "'" + name + "' is not defined."); log(line.first, line.second, "'" + name + "' is not defined.");
@ -1208,10 +1205,13 @@ private:
start = cxt.start; start = cxt.start;
grammar["%ANCHOR%"] <= anc();
grammar["%ANCHOR%"] = [](const char* s, size_t l) { return s; };
return cxt.grammar; return cxt.grammar;
} }
std::string resolve_escape_sequence(const char*s, size_t l) { std::string resolve_escape_sequence(const char* s, size_t l) {
std::string r; std::string r;
r.reserve(l); r.reserve(l);
@ -1364,7 +1364,7 @@ private:
}; };
/*----------------------------------------------------------------------------- /*-----------------------------------------------------------------------------
* Utilities * Simple interface
*---------------------------------------------------------------------------*/ *---------------------------------------------------------------------------*/
struct match struct match

View File

@ -161,7 +161,7 @@ TEST_CASE("Simple calculator test", "[general]")
}; };
parser["Multitive"] = [](const vector<any>& v) { parser["Multitive"] = [](const vector<any>& v) {
return v.size() == 1 ? int(v[0]) : v[0].get<int>() * v[1].get<int>(); return v.size() == 1 ? v[0].get<int>() : v[0].get<int>() * v[1].get<int>();
}; };
parser["Primary"] = [](const vector<any>& v) { parser["Primary"] = [](const vector<any>& v) {