mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2024-12-22 11:55:30 +00:00
Added 'anchor' support. Removed implecit cast operators from 'any'.
This commit is contained in:
parent
81ca85cba5
commit
d2ad29359e
22
README.md
22
README.md
@ -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;
|
||||||
|
80
peglib.h
80
peglib.h
@ -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
|
||||||
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user