diff --git a/README.md b/README.md index 0a3a037..92571ca 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ C++11 header-only [PEG](http://en.wikipedia.org/wiki/Parsing_expression_grammar) The PEG syntax is well described on page 2 in the [document](http://pdos.csail.mit.edu/papers/parsing:popl04.pdf). *cpp-peglib* also supports the following additional syntax for now: - * `<` ... `>` (Anchor operator) + * `<` ... `>` (Token boundary operator) * `$<` ... `>` (Capture operator) * `$name<` ... `>` (Named capture operator) * `~` (Ignore operator) @@ -25,7 +25,7 @@ This is a simple calculator sample. It shows how to define grammar, associate sa #include #include -using namespace peglib; +using namespace peg; using namespace std; int main(void) { @@ -38,7 +38,7 @@ int main(void) { Number <- [0-9]+ )"; - peg parser(syntax); + parser parser(syntax); // (3) Setup an action parser["Additive"] = [](const SemanticValues& sv) { @@ -111,13 +111,13 @@ struct SemanticValues : protected std::vector } ``` -`peglib::any` class is very similar to [boost::any](http://www.boost.org/doc/libs/1_57_0/doc/html/any.html). You can obtain a value by castning it to the actual type. In order to determine the actual type, you have to check the return value type of the child action for the semantic value. +`peg::any` class is very similar to [boost::any](http://www.boost.org/doc/libs/1_57_0/doc/html/any.html). You can obtain a value by castning it to the actual type. In order to determine the actual type, you have to check the return value type of the child action for the semantic value. `const char* s, size_t n` gives a pointer and length of the matched string. This is same as `sv.s` and `sv.n`. `any& dt` is a data object which can be used by the user for whatever purposes. -The following example uses `<` ... ` >` operators. They are the *anchor* operators. Each anchor operator creates a semantic value that contains `const char*` of the position. It could be useful to eliminate unnecessary characters. +The following example uses `<` ... ` >` operators. They are the *token boundary* operators. Each token boundary operator creates a semantic value that contains `const char*` of the position. It could be useful to eliminate unnecessary characters. ```c++ auto syntax = R"( @@ -139,7 +139,7 @@ auto ret = pg.parse(" token1, token2 "); We can ignore unnecessary semantic values from the list by using `~` operator. ```c++ -peglib::peg parser( +peg::pegparser parser( " ROOT <- _ ITEM (',' _ ITEM _)* " " ITEM <- ([a-z])+ " " ~_ <- [ \t]* " @@ -155,22 +155,22 @@ auto ret = parser.parse(" item1, item2 "); The following grammar is same as the above. ```c++ -peglib::peg parser( +peg::parser parser( " ROOT <- ~_ ITEM (',' ~_ ITEM ~_)* " " ITEM <- ([a-z])+ " " _ <- [ \t]* " ); ``` -*Semantic predicate* support is available. We can do it by throwing a `peglib::parse_error` exception in a semantic action. +*Semantic predicate* support is available. We can do it by throwing a `peg::parse_error` exception in a semantic action. ```c++ -peglib::peg parser("NUMBER <- [0-9]+"); +peg::parser parser("NUMBER <- [0-9]+"); parser["NUMBER"] = [](const SemanticValues& sv) { auto val = stol(sv.str(), nullptr, 10); if (val != 100) { - throw peglib::parse_error("value error!!"); + throw peg::parse_error("value error!!"); } return val; }; @@ -189,12 +189,12 @@ Simple interface *cpp-peglib* provides std::regex-like simple interface for trivial tasks. -`peglib::peg_match` tries to capture strings in the `$< ... >` operator and store them into `peglib::match` object. +`peg::peg_match` tries to capture strings in the `$< ... >` operator and store them into `peg::match` object. ```c++ -peglib::match m; +peg::match m; -auto ret = peglib::peg_match( +auto ret = peg::peg_match( R"( ROOT <- _ ('[' $< TAG_NAME > ']' _)* TAG_NAME <- (!']' .)+ @@ -213,9 +213,9 @@ assert(m.str(3) == "tag-3"); It also supports named capture with the `$name<` ... `>` operator. ```c++ -peglib::match m; +peg::match m; -auto ret = peglib::peg_match( +auto ret = peg::peg_match( R"( ROOT <- _ ('[' $test< TAG_NAME > ']' _)* TAG_NAME <- (!']' .)+ @@ -235,7 +235,7 @@ REQUIRE(m.str(cap[2]) == "tag-3"); There are some ways to *search* a peg pattern in a document. ```c++ -using namespace peglib; +using namespace peg; auto syntax = R"( ROOT <- '[' $< [a-z0-9]+ > ']' @@ -243,8 +243,8 @@ auto syntax = R"( auto s = " [tag1] [tag2] [tag3] "; -// peglib::peg_search -peg pg(syntax); +// peg::peg_search +parser pg(syntax); size_t pos = 0; auto n = strlen(s); match m; @@ -254,7 +254,7 @@ while (peg_search(pg, s + pos, n - pos, m)) { pos += m.length(); } -// peglib::peg_token_iterator +// peg::peg_token_iterator peg_token_iterator it(syntax, s); while (it != peg_token_iterator()) { cout << it->str() << endl; // entire match @@ -262,7 +262,7 @@ while (it != peg_token_iterator()) { ++it; } -// peglib::peg_token_range +// peg::peg_token_range for (auto& m: peg_token_range(syntax, s)) { cout << m.str() << endl; // entire match cout << m.str(1) << endl; // submatch #1 @@ -275,7 +275,7 @@ Make a parser with parser operators Instead of makeing a parser by parsing PEG syntax text, we can also construct a parser by hand with *parser operators*. Here is an example: ```c++ -using namespace peglib; +using namespace peg; using namespace std; vector tags; @@ -305,7 +305,7 @@ The following are available operators: | cls | Character class | | chr | Character | | dot | Any character | -| anc | Anchor character | +| tok | Token boundary | | ign | Ignore semantic value | | cap | Capture character | | usr | User defiend parser | @@ -337,7 +337,7 @@ Rules additional_rules = { } }; -peg g = peg(syntax, additional_rules); +auto g = parser(syntax, additional_rules); assert(g.parse(" Hello BNF! ")); ``` diff --git a/example/calc.cc b/example/calc.cc index 4fc18c1..a563d55 100644 --- a/example/calc.cc +++ b/example/calc.cc @@ -9,7 +9,7 @@ #include #include -using namespace peglib; +using namespace peg; using namespace std; int main(int argc, const char** argv) @@ -34,7 +34,7 @@ int main(int argc, const char** argv) return result; }; - peg parser(R"( + parser parser(R"( EXPRESSION <- _ TERM (TERM_OPERATOR TERM)* TERM <- FACTOR (FACTOR_OPERATOR FACTOR)* FACTOR <- NUMBER / '(' _ EXPRESSION ')' _ diff --git a/example/calc2.cc b/example/calc2.cc index 3b8ee45..0d9a040 100644 --- a/example/calc2.cc +++ b/example/calc2.cc @@ -9,7 +9,7 @@ #include #include -using namespace peglib; +using namespace peg; using namespace std; // diff --git a/example/calc3.cc b/example/calc3.cc index 36d93bb..2761924 100644 --- a/example/calc3.cc +++ b/example/calc3.cc @@ -9,7 +9,7 @@ #include #include -using namespace peglib; +using namespace peg; using namespace std; int main(int argc, const char** argv) @@ -39,7 +39,7 @@ int main(int argc, const char** argv) } }; - peg parser(R"( + parser parser(R"( EXPRESSION <- _ TERM (TERM_OPERATOR TERM)* TERM <- FACTOR (FACTOR_OPERATOR FACTOR)* FACTOR <- NUMBER / '(' _ EXPRESSION ')' _ diff --git a/language/culebra/culebra.h b/language/culebra/culebra.h index e5324ef..edb00d2 100644 --- a/language/culebra/culebra.h +++ b/language/culebra/culebra.h @@ -86,9 +86,9 @@ const auto grammar_ = R"( )"; -inline peglib::peg& get_parser() +inline peg::parser& get_parser() { - static peglib::peg parser; + static peg::parser parser; static bool initialized = false; if (!initialized) { @@ -337,7 +337,7 @@ struct Value } Type type; - peglib::any v; + peg::any v; }; struct Symbol { @@ -408,7 +408,7 @@ struct Environment std::map dictionary; }; -typedef std::function Debugger; +typedef std::function Debugger; inline bool ObjectValue::has(const std::string& name) const { if (properties->find(name) == properties->end()) { @@ -544,7 +544,7 @@ struct Interpreter : debugger_(debugger) { } - Value exec(const peglib::Ast& ast, std::shared_ptr env) { + Value exec(const peg::Ast& ast, std::shared_ptr env) { try { return eval(ast, env); } catch (const Value& val) { @@ -553,8 +553,8 @@ struct Interpreter } private: - Value eval(const peglib::Ast& ast, std::shared_ptr env) { - using peglib::operator"" _; + Value eval(const peg::Ast& ast, std::shared_ptr env) { + using peg::operator"" _; if (debugger_) { if (ast.original_tag == "STATEMENT"_) { @@ -598,7 +598,7 @@ private: throw std::logic_error("invalid Ast type"); } - Value eval_statements(const peglib::Ast& ast, std::shared_ptr env) { + Value eval_statements(const peg::Ast& ast, std::shared_ptr env) { if (ast.is_token) { return eval(ast, env); } else if (ast.nodes.empty()) { @@ -612,7 +612,7 @@ private: return eval(**it, env); } - Value eval_while(const peglib::Ast& ast, std::shared_ptr env) { + Value eval_while(const peg::Ast& ast, std::shared_ptr env) { for (;;) { auto cond = eval(*ast.nodes[0], env); if (!cond.to_bool()) { @@ -623,7 +623,7 @@ private: return Value(); } - Value eval_if(const peglib::Ast& ast, std::shared_ptr env) { + Value eval_if(const peg::Ast& ast, std::shared_ptr env) { const auto& nodes = ast.nodes; for (auto i = 0u; i < nodes.size(); i += 2) { @@ -640,7 +640,7 @@ private: return Value(); } - Value eval_function(const peglib::Ast& ast, std::shared_ptr env) { + Value eval_function(const peg::Ast& ast, std::shared_ptr env) { std::vector params; for (auto node: ast.nodes[0]->nodes) { auto mut = node->nodes[0]->token == "mut"; @@ -659,7 +659,7 @@ private: )); }; - Value eval_function_call(const peglib::Ast& ast, std::shared_ptr env, const Value& val) { + Value eval_function_call(const peg::Ast& ast, std::shared_ptr env, const Value& val) { const auto& f = val.to_function(); const auto& params = *f.params; const auto& args = ast.nodes; @@ -686,7 +686,7 @@ private: throw std::runtime_error(msg); } - Value eval_array_reference(const peglib::Ast& ast, std::shared_ptr env, const Value& val) { + Value eval_array_reference(const peg::Ast& ast, std::shared_ptr env, const Value& val) { const auto& arr = val.to_array(); auto idx = eval(ast, env).to_long(); if (0 <= idx && idx < static_cast(arr.values->size())) { @@ -697,7 +697,7 @@ private: return val; } - Value eval_property(const peglib::Ast& ast, std::shared_ptr env, const Value& val) { + Value eval_property(const peg::Ast& ast, std::shared_ptr env, const Value& val) { const auto& obj = val.to_object(); auto name = ast.token; if (!obj.has(name)) { @@ -717,8 +717,8 @@ private: return prop; } - Value eval_call(const peglib::Ast& ast, std::shared_ptr env) { - using peglib::operator"" _; + Value eval_call(const peg::Ast& ast, std::shared_ptr env) { + using peg::operator"" _; Value val = eval(*ast.nodes[0], env); @@ -736,11 +736,11 @@ private: return std::move(val); } - Value eval_block(const peglib::Ast& ast, std::shared_ptr env) { + Value eval_block(const peg::Ast& ast, std::shared_ptr env) { return Value(); } - Value eval_logical_or(const peglib::Ast& ast, std::shared_ptr env) { + Value eval_logical_or(const peg::Ast& ast, std::shared_ptr env) { assert(ast.nodes.size() > 1); // if the size is 1, thes node will be hoisted. Value val; for (auto node: ast.nodes) { @@ -752,7 +752,7 @@ private: return std::move(val); } - Value eval_logical_and(const peglib::Ast& ast, std::shared_ptr env) { + Value eval_logical_and(const peg::Ast& ast, std::shared_ptr env) { Value val; for (auto node: ast.nodes) { val = eval(*node, env); @@ -763,7 +763,7 @@ private: return std::move(val); } - Value eval_condition(const peglib::Ast& ast, std::shared_ptr env) { + Value eval_condition(const peg::Ast& ast, std::shared_ptr env) { assert(ast.nodes.size() == 3); // if the size is 1, thes node will be hoisted. auto lhs = eval(*ast.nodes[0], env); @@ -779,22 +779,22 @@ private: else { throw std::logic_error("invalid internal condition."); } } - Value eval_unary_plus(const peglib::Ast& ast, std::shared_ptr env) { + Value eval_unary_plus(const peg::Ast& ast, std::shared_ptr env) { assert(ast.nodes.size() == 2); // if the size is 1, thes node will be hoisted. return eval(*ast.nodes[1], env); } - Value eval_unary_minus(const peglib::Ast& ast, std::shared_ptr env) { + Value eval_unary_minus(const peg::Ast& ast, std::shared_ptr env) { assert(ast.nodes.size() == 2); // if the size is 1, thes node will be hoisted. return Value(eval(*ast.nodes[1], env).to_long() * -1); } - Value eval_unary_not(const peglib::Ast& ast, std::shared_ptr env) { + Value eval_unary_not(const peg::Ast& ast, std::shared_ptr env) { assert(ast.nodes.size() == 2); // if the size is 1, thes node will be hoisted. return Value(!eval(*ast.nodes[1], env).to_bool()); } - Value eval_bin_expression(const peglib::Ast& ast, std::shared_ptr env) { + Value eval_bin_expression(const peg::Ast& ast, std::shared_ptr env) { auto ret = eval(*ast.nodes[0], env).to_long(); for (auto i = 1u; i < ast.nodes.size(); i += 2) { auto val = eval(*ast.nodes[i + 1], env).to_long(); @@ -820,7 +820,7 @@ private: return keywords.find(ident) != keywords.end(); } - Value eval_assignment(const peglib::Ast& ast, std::shared_ptr env) { + Value eval_assignment(const peg::Ast& ast, std::shared_ptr env) { auto end = ast.nodes.size() - 1; auto mut = ast.nodes[0]->token == "mut"; @@ -837,7 +837,7 @@ private: } return std::move(val); } else { - using peglib::operator"" _; + using peg::operator"" _; Value lval = eval(*ast.nodes[1], env); @@ -882,11 +882,11 @@ private: } }; - Value eval_identifier(const peglib::Ast& ast, std::shared_ptr env) { + Value eval_identifier(const peg::Ast& ast, std::shared_ptr env) { return env->get(ast.token); }; - Value eval_object(const peglib::Ast& ast, std::shared_ptr env) { + Value eval_object(const peg::Ast& ast, std::shared_ptr env) { ObjectValue obj; for (auto i = 0u; i < ast.nodes.size(); i++) { const auto& prop = *ast.nodes[i]; @@ -898,7 +898,7 @@ private: return Value(std::move(obj)); } - Value eval_array(const peglib::Ast& ast, std::shared_ptr env) { + Value eval_array(const peg::Ast& ast, std::shared_ptr env) { ArrayValue arr; for (auto i = 0u; i < ast.nodes.size(); i++) { auto expr = ast.nodes[i]; @@ -908,19 +908,19 @@ private: return Value(std::move(arr)); } - Value eval_undefined(const peglib::Ast& ast, std::shared_ptr env) { + Value eval_undefined(const peg::Ast& ast, std::shared_ptr env) { return Value(); }; - Value eval_bool(const peglib::Ast& ast, std::shared_ptr env) { + Value eval_bool(const peg::Ast& ast, std::shared_ptr env) { return Value(ast.token == "true"); }; - Value eval_number(const peglib::Ast& ast, std::shared_ptr env) { + Value eval_number(const peg::Ast& ast, std::shared_ptr env) { return Value(stol(ast.token)); }; - Value eval_interpolated_string(const peglib::Ast& ast, std::shared_ptr env) { + Value eval_interpolated_string(const peg::Ast& ast, std::shared_ptr env) { std::string s; for (auto node: ast.nodes) { const auto& val = eval(*node, env); @@ -933,7 +933,7 @@ private: return Value(std::move(s)); }; - void eval_return(const peglib::Ast& ast, std::shared_ptr env) { + void eval_return(const peg::Ast& ast, std::shared_ptr env) { if (ast.nodes.empty()) { throw Value(); } else { @@ -951,7 +951,7 @@ inline bool run( size_t len, Value& val, std::vector& msgs, - std::shared_ptr& ast, + std::shared_ptr& ast, Debugger debugger = nullptr) { try { @@ -964,7 +964,7 @@ inline bool run( }; if (parser.parse_n(expr, len, ast, path.c_str())) { - ast = peglib::AstOptimizer(true, { "PARAMETERS", "ARGUMENTS", "OBJECT", "ARRAY", "RETURN" }).optimize(ast); + ast = peg::AstOptimizer(true, { "PARAMETERS", "ARGUMENTS", "OBJECT", "ARRAY", "RETURN" }).optimize(ast); val = Interpreter(debugger).exec(*ast, env); return true; } diff --git a/language/culebra/main.cc b/language/culebra/main.cc index e723f7c..1cfa465 100644 --- a/language/culebra/main.cc +++ b/language/culebra/main.cc @@ -6,7 +6,7 @@ #include using namespace culebra; -using namespace peglib; +using namespace peg; using namespace std; bool read_file(const char* path, vector& buff) diff --git a/language/pl0/pl0.cc b/language/pl0/pl0.cc index 221d3e5..c5a6447 100644 --- a/language/pl0/pl0.cc +++ b/language/pl0/pl0.cc @@ -10,7 +10,7 @@ #include #include -using namespace peglib; +using namespace peg; using namespace std; /* @@ -331,7 +331,7 @@ private: // compare <- expression compare_op expression const auto& nodes = ast->nodes; auto lval = eval_expression(nodes[0], env); - auto op = peglib::str2tag(nodes[1]->token.c_str()); + auto op = peg::str2tag(nodes[1]->token.c_str()); auto rval = eval_expression(nodes[2], env); switch (op) { case "="_: return lval == rval; @@ -427,7 +427,7 @@ int main(int argc, const char** argv) } // Setup a PEG parser - peg parser(grammar); + parser parser(grammar); parser.enable_ast(); parser.log = [&](size_t ln, size_t col, const string& msg) { cerr << format_error_message(path, ln, col, msg) << endl; diff --git a/lint/cmdline/peglint.cc b/lint/cmdline/peglint.cc index 1125e64..ebfb0af 100644 --- a/lint/cmdline/peglint.cc +++ b/lint/cmdline/peglint.cc @@ -59,13 +59,13 @@ int main(int argc, const char** argv) return -1; } - peglib::peg peg; + peg::parser parser; - peg.log = [&](auto ln, auto col, const auto& msg) { + parser.log = [&](auto ln, auto col, const auto& msg) { cerr << syntax_path << ":" << ln << ":" << col << ": " << msg << endl; }; - if (!peg.load_grammar(syntax.data(), syntax.size())) { + if (!parser.load_grammar(syntax.data(), syntax.size())) { return -1; } @@ -84,22 +84,22 @@ int main(int argc, const char** argv) source_path = "[commendline]"; } - peg.log = [&](auto ln, auto col, const auto& msg) { + parser.log = [&](auto ln, auto col, const auto& msg) { cerr << source_path << ":" << ln << ":" << col << ": " << msg << endl; }; if (opt_ast) { - peg.enable_ast(); + parser.enable_ast(); - std::shared_ptr ast; - if (!peg.parse_n(source.data(), source.size(), ast)) { + std::shared_ptr ast; + if (!parser.parse_n(source.data(), source.size(), ast)) { return -1; } - ast = peglib::AstOptimizer(opt_optimize_ast_nodes).optimize(ast); - peglib::AstPrint::print(ast); + ast = peg::AstOptimizer(opt_optimize_ast_nodes).optimize(ast); + peg::AstPrint::print(ast); } else { - if (!peg.parse_n(source.data(), source.size())) { + if (!parser.parse_n(source.data(), source.size())) { return -1; } } diff --git a/peglib.h b/peglib.h index 2ed79e0..cb7558b 100644 --- a/peglib.h +++ b/peglib.h @@ -23,7 +23,7 @@ #include #include -namespace peglib { +namespace peg { extern void* enabler; @@ -846,10 +846,10 @@ private: std::string name_; }; -class Anchor : public Ope +class TokenBoundary : public Ope { public: - Anchor(const std::shared_ptr& ope) : ope_(ope) {} + TokenBoundary(const std::shared_ptr& ope) : ope_(ope) {} size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override { const auto& rule = *ope_; @@ -979,7 +979,7 @@ struct Ope::Visitor virtual void visit(Character& ope) {} virtual void visit(AnyCharacter& ope) {} virtual void visit(Capture& ope) {} - virtual void visit(Anchor& ope) {} + virtual void visit(TokenBoundary& ope) {} virtual void visit(Ignore& ope) {} virtual void visit(User& ope) {} virtual void visit(WeakHolder& ope) {} @@ -1005,7 +1005,7 @@ struct AssignIDToDefinition : public Ope::Visitor void visit(AndPredicate& ope) override { ope.ope_->accept(*this); } void visit(NotPredicate& ope) override { ope.ope_->accept(*this); } void visit(Capture& ope) override { ope.ope_->accept(*this); } - void visit(Anchor& ope) override { ope.ope_->accept(*this); } + void visit(TokenBoundary& ope) override { ope.ope_->accept(*this); } void visit(Ignore& ope) override { ope.ope_->accept(*this); } void visit(WeakHolder& ope) override { ope.weak_.lock()->accept(*this); } void visit(Holder& ope) override; @@ -1016,7 +1016,7 @@ struct AssignIDToDefinition : public Ope::Visitor struct IsToken : public Ope::Visitor { - IsToken() : has_anchor(false), has_rule(false) {} + IsToken() : has_token_boundary(false), has_rule(false) {} void visit(Sequence& ope) override { for (auto op: ope.opes_) { @@ -1032,16 +1032,16 @@ struct IsToken : public Ope::Visitor void visit(OneOrMore& ope) override { ope.ope_->accept(*this); } void visit(Option& ope) override { ope.ope_->accept(*this); } void visit(Capture& ope) override { ope.ope_->accept(*this); } - void visit(Anchor& ope) override { has_anchor = true; } + void visit(TokenBoundary& ope) override { has_token_boundary = true; } void visit(Ignore& ope) override { ope.ope_->accept(*this); } void visit(WeakHolder& ope) override { ope.weak_.lock()->accept(*this); } void visit(DefinitionReference& ope) override { has_rule = true; } bool is_token() const { - return has_anchor || !has_rule; + return has_token_boundary || !has_rule; } - bool has_anchor; + bool has_token_boundary; bool has_rule; }; @@ -1219,8 +1219,8 @@ inline size_t Holder::parse(const char* s, size_t n, SemanticValues& sv, Context size_t len; any val; - const char* anchors = s; - size_t anchorn = n; + const char* token_boundary_s = s; + size_t token_boundary_n = n; c.packrat(s, outer_->id, len, val, [&](any& val) { auto& chldsv = c.push(); @@ -1228,13 +1228,13 @@ inline size_t Holder::parse(const char* s, size_t n, SemanticValues& sv, Context const auto& rule = *ope_; len = rule.parse(s, n, chldsv, c, dt); - anchorn = len; + token_boundary_n = len; // Invoke action if (success(len)) { if (chldsv.s) { - anchors = chldsv.s; - anchorn = chldsv.n; + token_boundary_s = chldsv.s; + token_boundary_n = chldsv.n; } else { chldsv.s = s; chldsv.n = len; @@ -1255,7 +1255,7 @@ inline size_t Holder::parse(const char* s, size_t n, SemanticValues& sv, Context }); if (success(len) && !outer_->ignoreSemanticValue) { - sv.emplace_back(val, outer_->name.c_str(), anchors, anchorn); + sv.emplace_back(val, outer_->name.c_str(), token_boundary_s, token_boundary_n); } if (fail(len) && outer_->error_message && !c.message_pos) { @@ -1304,7 +1304,7 @@ inline void CharacterClass::accept(Visitor& v) { v.visit(*this); } inline void Character::accept(Visitor& v) { v.visit(*this); } inline void AnyCharacter::accept(Visitor& v) { v.visit(*this); } inline void Capture::accept(Visitor& v) { v.visit(*this); } -inline void Anchor::accept(Visitor& v) { v.visit(*this); } +inline void TokenBoundary::accept(Visitor& v) { v.visit(*this); } inline void Ignore::accept(Visitor& v) { v.visit(*this); } inline void User::accept(Visitor& v) { v.visit(*this); } inline void WeakHolder::accept(Visitor& v) { v.visit(*this); } @@ -1379,8 +1379,8 @@ inline std::shared_ptr cap(const std::shared_ptr& ope, MatchAction ma) return std::make_shared(ope, ma, (size_t)-1, std::string()); } -inline std::shared_ptr anc(const std::shared_ptr& ope) { - return std::make_shared(ope); +inline std::shared_ptr tok(const std::shared_ptr& ope) { + return std::make_shared(ope); } inline std::shared_ptr ign(const std::shared_ptr& ope) { @@ -1422,7 +1422,7 @@ typedef std::function Log; typedef std::unordered_map> Rules; -class PEGParser +class ParserGenerator { public: static std::shared_ptr parse( @@ -1453,12 +1453,12 @@ public: } private: - static PEGParser& get_instance() { - static PEGParser instance; + static ParserGenerator& get_instance() { + static ParserGenerator instance; return instance; } - PEGParser() { + ParserGenerator() { make_grammar(); setup_actions(); } @@ -1536,7 +1536,7 @@ private: void visit(Capture& ope) override { ope.ope_->accept(*this); } - void visit(Anchor& ope) override { + void visit(TokenBoundary& ope) override { ope.ope_->accept(*this); } void visit(Ignore& ope) override { @@ -1591,10 +1591,10 @@ private: g["IdentStart"] <= cls("a-zA-Z_\x80-\xff"); g["IdentRest"] <= cho(g["IdentStart"], cls("0-9")); - g["Literal"] <= cho(seq(cls("'"), anc(zom(seq(npd(cls("'")), g["Char"]))), cls("'"), g["Spacing"]), - seq(cls("\""), anc(zom(seq(npd(cls("\"")), g["Char"]))), cls("\""), g["Spacing"])); + g["Literal"] <= cho(seq(cls("'"), tok(zom(seq(npd(cls("'")), g["Char"]))), cls("'"), g["Spacing"]), + seq(cls("\""), tok(zom(seq(npd(cls("\"")), g["Char"]))), cls("\""), g["Spacing"])); - g["Class"] <= seq(chr('['), anc(zom(seq(npd(chr(']')), g["Range"]))), chr(']'), g["Spacing"]); + g["Class"] <= seq(chr('['), tok(zom(seq(npd(chr(']')), g["Range"]))), chr(']'), g["Spacing"]); g["Range"] <= cho(seq(g["Char"], chr('-'), g["Char"]), g["Char"]); g["Char"] <= cho(seq(chr('\\'), cls("nrt'\"[]\\")), @@ -1623,7 +1623,7 @@ private: g["Begin"] <= seq(chr('<'), g["Spacing"]); g["End"] <= seq(chr('>'), g["Spacing"]); - g["BeginCap"] <= seq(chr('$'), anc(opt(g["Identifier"])), chr('<'), g["Spacing"]); + g["BeginCap"] <= seq(chr('$'), tok(opt(g["Identifier"])), chr('<'), g["Spacing"]); g["EndCap"] <= seq(lit(">"), g["Spacing"]); g["IGNORE"] <= chr('~'); @@ -1742,8 +1742,8 @@ private: case 1: { // (Expression) return sv[1].get>(); } - case 2: { // Anchor - return anc(sv[1].get>()); + case 2: { // TokenBoundary + return tok(sv[1].get>()); } case 3: { // Capture auto name = std::string(sv[0].s, sv[0].n); @@ -2100,33 +2100,33 @@ struct EmptyType {}; typedef AstBase Ast; /*----------------------------------------------------------------------------- - * peg + * parser *---------------------------------------------------------------------------*/ -class peg +class parser { public: - peg() = default; + parser() = default; - peg(const char* s, size_t n, const Rules& rules) { + parser(const char* s, size_t n, const Rules& rules) { load_grammar(s, n, rules); } - peg(const char* s, const Rules& rules) - : peg(s, strlen(s), rules) {} + parser(const char* s, const Rules& rules) + : parser(s, strlen(s), rules) {} - peg(const char* s, size_t n) - : peg(s, n, Rules()) {} + parser(const char* s, size_t n) + : parser(s, n, Rules()) {} - peg(const char* s) - : peg(s, strlen(s), Rules()) {} + parser(const char* s) + : parser(s, strlen(s), Rules()) {} operator bool() { return grammar_ != nullptr; } bool load_grammar(const char* s, size_t n, const Rules& rules) { - grammar_ = PEGParser::parse( + grammar_ = ParserGenerator::parse( s, n, rules, start_, @@ -2253,7 +2253,7 @@ public: } template - peg& enable_ast() { + parser& enable_ast() { for (auto& x: *grammar_) { const auto& name = x.first; auto& rule = x.second; @@ -2396,7 +2396,7 @@ struct match inline bool peg_match(const char* syntax, const char* s, match& m) { m.matches.clear(); - peg pg(syntax); + parser pg(syntax); pg.match_action = [&](const char* s, size_t n, size_t id, const std::string& name) { m.matches.push_back(match::Item{ s, n, id, name }); }; @@ -2411,11 +2411,11 @@ inline bool peg_match(const char* syntax, const char* s, match& m) { } inline bool peg_match(const char* syntax, const char* s) { - peg pg(syntax); - return pg.parse(s); + parser parser(syntax); + return parser.parse(s); } -inline bool peg_search(peg& pg, const char* s, size_t n, match& m) { +inline bool peg_search(parser& pg, const char* s, size_t n, match& m) { m.matches.clear(); pg.match_action = [&](const char* s, size_t n, size_t id, const std::string& name) { @@ -2432,18 +2432,18 @@ inline bool peg_search(peg& pg, const char* s, size_t n, match& m) { return false; } -inline bool peg_search(peg& pg, const char* s, match& m) { +inline bool peg_search(parser& pg, const char* s, match& m) { auto n = strlen(s); return peg_search(pg, s, n, m); } inline bool peg_search(const char* syntax, const char* s, size_t n, match& m) { - peg pg(syntax); + parser pg(syntax); return peg_search(pg, s, n, m); } inline bool peg_search(const char* syntax, const char* s, match& m) { - peg pg(syntax); + parser pg(syntax); auto n = strlen(s); return peg_search(pg, s, n, m); } @@ -2513,7 +2513,7 @@ private: } } - peg peg_; + parser peg_; const char* s_; size_t l_; size_t pos_; @@ -2549,7 +2549,7 @@ private: peg_token_iterator end_iter; }; -} // namespace peglib +} // namespace peg #endif diff --git a/test/test.cc b/test/test.cc index 0b0c212..46e3842 100644 --- a/test/test.cc +++ b/test/test.cc @@ -7,7 +7,7 @@ TEST_CASE("Simple syntax test", "[general]") { - peglib::peg parser( + peg::parser parser( " ROOT <- _ " " _ <- ' ' " ); @@ -18,14 +18,14 @@ TEST_CASE("Simple syntax test", "[general]") TEST_CASE("Empty syntax test", "[general]") { - peglib::peg parser(""); + peg::parser parser(""); bool ret = parser; REQUIRE(ret == false); } TEST_CASE("String capture test", "[general]") { - peglib::peg parser( + peg::parser parser( " ROOT <- _ ('[' TAG_NAME ']' _)* " " TAG_NAME <- (!']' .)+ " " _ <- [ \t]* " @@ -33,7 +33,7 @@ TEST_CASE("String capture test", "[general]") std::vector tags; - parser["TAG_NAME"] = [&](const peglib::SemanticValues& sv) { + parser["TAG_NAME"] = [&](const peg::SemanticValues& sv) { tags.push_back(sv.str()); }; @@ -48,8 +48,8 @@ TEST_CASE("String capture test", "[general]") TEST_CASE("String capture test with match", "[general]") { - peglib::match m; - auto ret = peglib::peg_match( + peg::match m; + auto ret = peg::peg_match( " ROOT <- _ ('[' $< TAG_NAME > ']' _)* " " TAG_NAME <- (!']' .)+ " " _ <- [ \t]* ", @@ -63,7 +63,7 @@ TEST_CASE("String capture test with match", "[general]") REQUIRE(m.str(3) == "tag-3"); } -using namespace peglib; +using namespace peg; using namespace std; TEST_CASE("String capture test2", "[general]") @@ -93,7 +93,7 @@ TEST_CASE("String capture test3", "[general]") " _ <- [ \t\r\n]* " ; - peg pg(syntax); + parser pg(syntax); std::vector tags; @@ -112,9 +112,9 @@ TEST_CASE("String capture test3", "[general]") TEST_CASE("Named capture test", "[general]") { - peglib::match m; + peg::match m; - auto ret = peglib::peg_match( + auto ret = peg::peg_match( " ROOT <- _ ('[' $test< TAG_NAME > ']' _)* " " TAG_NAME <- (!']' .)+ " " _ <- [ \t]* ", @@ -180,14 +180,14 @@ TEST_CASE("Visit test", "[general]") TEST_CASE("Token check test", "[general]") { - peg parser( + parser parser( " EXPRESSION <- _ TERM (TERM_OPERATOR TERM)* " " TERM <- FACTOR (FACTOR_OPERATOR FACTOR)* " " FACTOR <- NUMBER / '(' _ EXPRESSION ')' _ " " TERM_OPERATOR <- < [-+] > _ " " FACTOR_OPERATOR <- < [/*] > _ " " NUMBER <- < [0-9]+ > _ " - " ~_ <- [ \t\r\n]* " + " _ <- [ \t\r\n]* " ); REQUIRE(parser["EXPRESSION"].is_token == false); @@ -199,7 +199,7 @@ TEST_CASE("Token check test", "[general]") TEST_CASE("Lambda action test", "[general]") { - peg parser( + parser parser( " START <- (CHAR)* " " CHAR <- . "); @@ -215,7 +215,7 @@ TEST_CASE("Lambda action test", "[general]") TEST_CASE("Skip token test", "[general]") { - peglib::peg parser( + peg::parser parser( " ROOT <- _ ITEM (',' _ ITEM _)* " " ITEM <- ([a-z0-9])+ " " ~_ <- [ \t]* " @@ -232,7 +232,7 @@ TEST_CASE("Skip token test", "[general]") TEST_CASE("Backtracking test", "[general]") { - peg parser( + parser parser( " START <- PAT1 / PAT2 " " PAT1 <- HELLO ' One' " " PAT2 <- HELLO ' Two' " @@ -253,7 +253,7 @@ TEST_CASE("Backtracking test", "[general]") TEST_CASE("Backtracking with AST", "[general]") { - peg parser(R"( + parser parser(R"( S <- A? B (A B)* A A <- 'a' B <- 'b' @@ -268,7 +268,7 @@ TEST_CASE("Backtracking with AST", "[general]") TEST_CASE("Octal/Hex value test", "[general]") { - peglib::peg parser( + peg::parser parser( R"( ROOT <- '\132\x7a' )" ); @@ -281,7 +281,7 @@ TEST_CASE("mutable lambda test", "[general]") { vector vec; - peg pg("ROOT <- 'mutable lambda test'"); + parser pg("ROOT <- 'mutable lambda test'"); // This test makes sure if the following code can be compiled. pg["TOKEN"] = [=](const SemanticValues& sv) mutable { @@ -297,7 +297,7 @@ TEST_CASE("Simple calculator test", "[general]") " Primary <- '(' Additive ')' / Number " " Number <- [0-9]+ "; - peg parser(syntax); + parser parser(syntax); parser["Additive"] = [](const SemanticValues& sv) { switch (sv.choice) { @@ -382,7 +382,7 @@ TEST_CASE("Calculator test2", "[general]") ; string start; - auto grammar = PEGParser::parse(syntax, strlen(syntax), start, nullptr, nullptr); + auto grammar = ParserGenerator::parse(syntax, strlen(syntax), start, nullptr, nullptr); auto& g = *grammar; // Setup actions @@ -417,7 +417,7 @@ TEST_CASE("Calculator test2", "[general]") TEST_CASE("Calculator test3", "[general]") { // Parse syntax - peg parser( + parser parser( " # Grammar for Calculator...\n " " EXPRESSION <- TERM (TERM_OPERATOR TERM)* " " TERM <- FACTOR (FACTOR_OPERATOR FACTOR)* " @@ -458,7 +458,7 @@ TEST_CASE("Calculator test3", "[general]") TEST_CASE("Calculator test with AST", "[general]") { - peg parser( + parser parser( " EXPRESSION <- _ TERM (TERM_OPERATOR TERM)* " " TERM <- FACTOR (FACTOR_OPERATOR FACTOR)* " " FACTOR <- NUMBER / '(' _ EXPRESSION ')' _ " @@ -492,7 +492,7 @@ TEST_CASE("Calculator test with AST", "[general]") shared_ptr ast; auto ret = parser.parse("1+2*3*(4-5+6)/7-8", ast); - ast = peglib::AstOptimizer(true).optimize(ast); + ast = peg::AstOptimizer(true).optimize(ast); auto val = eval(*ast); REQUIRE(ret == true); @@ -501,7 +501,7 @@ TEST_CASE("Calculator test with AST", "[general]") TEST_CASE("Ignore semantic value test", "[general]") { - peg parser( + parser parser( " START <- ~HELLO WORLD " " HELLO <- 'Hello' _ " " WORLD <- 'World' _ " @@ -520,7 +520,7 @@ TEST_CASE("Ignore semantic value test", "[general]") TEST_CASE("Ignore semantic value of 'or' predicate test", "[general]") { - peg parser( + parser parser( " START <- _ !DUMMY HELLO_WORLD '.' " " HELLO_WORLD <- HELLO 'World' _ " " HELLO <- 'Hello' _ " @@ -540,7 +540,7 @@ TEST_CASE("Ignore semantic value of 'or' predicate test", "[general]") TEST_CASE("Ignore semantic value of 'and' predicate test", "[general]") { - peg parser( + parser parser( " START <- _ &HELLO HELLO_WORLD '.' " " HELLO_WORLD <- HELLO 'World' _ " " HELLO <- 'Hello' _ " @@ -559,7 +559,7 @@ TEST_CASE("Ignore semantic value of 'and' predicate test", "[general]") TEST_CASE("Definition duplicates test", "[general]") { - peg parser( + parser parser( " A <- ''" " A <- ''" ); @@ -569,7 +569,7 @@ TEST_CASE("Definition duplicates test", "[general]") TEST_CASE("Left recursive test", "[left recursive]") { - peg parser( + parser parser( " A <- A 'a'" " B <- A 'a'" ); @@ -579,7 +579,7 @@ TEST_CASE("Left recursive test", "[left recursive]") TEST_CASE("Left recursive with option test", "[left recursive]") { - peg parser( + parser parser( " A <- 'a' / 'b'? B 'c' " " B <- A " ); @@ -589,7 +589,7 @@ TEST_CASE("Left recursive with option test", "[left recursive]") TEST_CASE("Left recursive with zom test", "[left recursive]") { - peg parser( + parser parser( " A <- 'a'* A* " ); @@ -598,7 +598,7 @@ TEST_CASE("Left recursive with zom test", "[left recursive]") TEST_CASE("Left recursive with empty string test", "[left recursive]") { - peg parser( + parser parser( " A <- '' A" ); @@ -626,7 +626,7 @@ TEST_CASE("User rule test", "[user rule]") } }; - peg g = peg(syntax, rules); + auto g = parser(syntax, rules); REQUIRE(g.parse(" Hello BNF! ") == true); } @@ -634,7 +634,7 @@ TEST_CASE("User rule test", "[user rule]") TEST_CASE("Semantic predicate test", "[predicate]") { - peg parser("NUMBER <- [0-9]+"); + parser parser("NUMBER <- [0-9]+"); parser["NUMBER"] = [](const SemanticValues& sv) { auto val = stol(sv.str(), nullptr, 10); @@ -655,7 +655,7 @@ TEST_CASE("Semantic predicate test", "[predicate]") TEST_CASE("Japanese character", "[unicode]") { - peglib::peg parser(R"( + peg::parser parser(R"( 文 <- 修飾語? 主語 述語 '。' 主語 <- 名詞 助詞 述語 <- 動詞 助詞 @@ -678,18 +678,18 @@ bool exact(Grammar& g, const char* d, const char* s) { } Grammar& make_peg_grammar() { - return PEGParser::grammar(); + return ParserGenerator::grammar(); } TEST_CASE("PEG Grammar", "[peg]") { - auto g = PEGParser::grammar(); + auto g = ParserGenerator::grammar(); REQUIRE(exact(g, "Grammar", " Definition <- a / ( b c ) / d \n rule2 <- [a-zA-Z][a-z0-9-]+ ") == true); } TEST_CASE("PEG Definition", "[peg]") { - auto g = PEGParser::grammar(); + auto g = ParserGenerator::grammar(); REQUIRE(exact(g, "Definition", "Definition <- a / (b c) / d ") == true); REQUIRE(exact(g, "Definition", "Definition <- a / b c / d ") == true); REQUIRE(exact(g, "Definition", "Definition ") == false); @@ -700,7 +700,7 @@ TEST_CASE("PEG Definition", "[peg]") TEST_CASE("PEG Expression", "[peg]") { - auto g = PEGParser::grammar(); + auto g = ParserGenerator::grammar(); REQUIRE(exact(g, "Expression", "a / (b c) / d ") == true); REQUIRE(exact(g, "Expression", "a / b c / d ") == true); REQUIRE(exact(g, "Expression", "a b ") == true); @@ -711,7 +711,7 @@ TEST_CASE("PEG Expression", "[peg]") TEST_CASE("PEG Sequence", "[peg]") { - auto g = PEGParser::grammar(); + auto g = ParserGenerator::grammar(); REQUIRE(exact(g, "Sequence", "a b c d ") == true); REQUIRE(exact(g, "Sequence", "") == true); REQUIRE(exact(g, "Sequence", "!") == false); @@ -721,7 +721,7 @@ TEST_CASE("PEG Sequence", "[peg]") TEST_CASE("PEG Prefix", "[peg]") { - auto g = PEGParser::grammar(); + auto g = ParserGenerator::grammar(); REQUIRE(exact(g, "Prefix", "&[a]") == true); REQUIRE(exact(g, "Prefix", "![']") == true); REQUIRE(exact(g, "Prefix", "-[']") == false); @@ -731,7 +731,7 @@ TEST_CASE("PEG Prefix", "[peg]") TEST_CASE("PEG Suffix", "[peg]") { - auto g = PEGParser::grammar(); + auto g = ParserGenerator::grammar(); REQUIRE(exact(g, "Suffix", "aaa ") == true); REQUIRE(exact(g, "Suffix", "aaa? ") == true); REQUIRE(exact(g, "Suffix", "aaa* ") == true); @@ -744,7 +744,7 @@ TEST_CASE("PEG Suffix", "[peg]") TEST_CASE("PEG Primary", "[peg]") { - auto g = PEGParser::grammar(); + auto g = ParserGenerator::grammar(); REQUIRE(exact(g, "Primary", "_Identifier0_ ") == true); REQUIRE(exact(g, "Primary", "_Identifier0_<-") == false); REQUIRE(exact(g, "Primary", "( _Identifier0_ _Identifier1_ )") == true); @@ -760,7 +760,7 @@ TEST_CASE("PEG Primary", "[peg]") TEST_CASE("PEG Identifier", "[peg]") { - auto g = PEGParser::grammar(); + auto g = ParserGenerator::grammar(); REQUIRE(exact(g, "Identifier", "_Identifier0_ ") == true); REQUIRE(exact(g, "Identifier", "0Identifier_ ") == false); REQUIRE(exact(g, "Identifier", "Iden|t ") == false); @@ -771,7 +771,7 @@ TEST_CASE("PEG Identifier", "[peg]") TEST_CASE("PEG IdentStart", "[peg]") { - auto g = PEGParser::grammar(); + auto g = ParserGenerator::grammar(); REQUIRE(exact(g, "IdentStart", "_") == true); REQUIRE(exact(g, "IdentStart", "a") == true); REQUIRE(exact(g, "IdentStart", "Z") == true); @@ -782,7 +782,7 @@ TEST_CASE("PEG IdentStart", "[peg]") TEST_CASE("PEG IdentRest", "[peg]") { - auto g = PEGParser::grammar(); + auto g = ParserGenerator::grammar(); REQUIRE(exact(g, "IdentRest", "_") == true); REQUIRE(exact(g, "IdentRest", "a") == true); REQUIRE(exact(g, "IdentRest", "Z") == true); @@ -793,7 +793,7 @@ TEST_CASE("PEG IdentRest", "[peg]") TEST_CASE("PEG Literal", "[peg]") { - auto g = PEGParser::grammar(); + auto g = ParserGenerator::grammar(); REQUIRE(exact(g, "Literal", "'abc' ") == true); REQUIRE(exact(g, "Literal", "'a\\nb\\tc' ") == true); REQUIRE(exact(g, "Literal", "'a\\277\tc' ") == true); @@ -812,7 +812,7 @@ TEST_CASE("PEG Literal", "[peg]") TEST_CASE("PEG Class", "[peg]") { - auto g = PEGParser::grammar(); + auto g = ParserGenerator::grammar(); REQUIRE(exact(g, "Class", "[]") == true); REQUIRE(exact(g, "Class", "[a]") == true); REQUIRE(exact(g, "Class", "[a-z]") == true); @@ -832,7 +832,7 @@ TEST_CASE("PEG Class", "[peg]") TEST_CASE("PEG Range", "[peg]") { - auto g = PEGParser::grammar(); + auto g = ParserGenerator::grammar(); REQUIRE(exact(g, "Range", "a") == true); REQUIRE(exact(g, "Range", "a-z") == true); REQUIRE(exact(g, "Range", "az") == false); @@ -843,7 +843,7 @@ TEST_CASE("PEG Range", "[peg]") TEST_CASE("PEG Char", "[peg]") { - auto g = PEGParser::grammar(); + auto g = ParserGenerator::grammar(); REQUIRE(exact(g, "Char", "\\n") == true); REQUIRE(exact(g, "Char", "\\r") == true); REQUIRE(exact(g, "Char", "\\t") == true); @@ -876,7 +876,7 @@ TEST_CASE("PEG Char", "[peg]") TEST_CASE("PEG Operators", "[peg]") { - auto g = PEGParser::grammar(); + auto g = ParserGenerator::grammar(); REQUIRE(exact(g, "LEFTARROW", "<-") == true); REQUIRE(exact(g, "SLASH", "/ ") == true); REQUIRE(exact(g, "AND", "& ") == true); @@ -891,7 +891,7 @@ TEST_CASE("PEG Operators", "[peg]") TEST_CASE("PEG Comment", "[peg]") { - auto g = PEGParser::grammar(); + auto g = ParserGenerator::grammar(); REQUIRE(exact(g, "Comment", "# Comment.\n") == true); REQUIRE(exact(g, "Comment", "# Comment.") == false); REQUIRE(exact(g, "Comment", " ") == false); @@ -900,7 +900,7 @@ TEST_CASE("PEG Comment", "[peg]") TEST_CASE("PEG Space", "[peg]") { - auto g = PEGParser::grammar(); + auto g = ParserGenerator::grammar(); REQUIRE(exact(g, "Space", " ") == true); REQUIRE(exact(g, "Space", "\t") == true); REQUIRE(exact(g, "Space", "\n") == true); @@ -910,7 +910,7 @@ TEST_CASE("PEG Space", "[peg]") TEST_CASE("PEG EndOfLine", "[peg]") { - auto g = PEGParser::grammar(); + auto g = ParserGenerator::grammar(); REQUIRE(exact(g, "EndOfLine", "\r\n") == true); REQUIRE(exact(g, "EndOfLine", "\n") == true); REQUIRE(exact(g, "EndOfLine", "\r") == true);