diff --git a/docs/native.wasm b/docs/native.wasm index 11b083b..6f42a98 100755 Binary files a/docs/native.wasm and b/docs/native.wasm differ diff --git a/lint/peglint.cc b/lint/peglint.cc index 5a8dc0a..7669767 100644 --- a/lint/peglint.cc +++ b/lint/peglint.cc @@ -124,9 +124,7 @@ int main(int argc, const char **argv) { cerr << source_path << ":" << ln << ":" << col << ": " << msg << endl; }; - if (opt_packrat) { - parser.enable_packrat_parsing(); - } + if (opt_packrat) { parser.enable_packrat_parsing(); } if (opt_trace) { size_t prev_pos = 0; @@ -180,8 +178,10 @@ int main(int argc, const char **argv) { matched = ", match '" + peg::escape_characters(s, len) + "'"; } std::cout << "L " << pos << "\t" << indent << ret << name << " #" - << c.trace_ids.back() << choice.str() << token << matched << std::endl; - }, opt_verbose); + << c.trace_ids.back() << choice.str() << token << matched + << std::endl; + }, + opt_verbose); } if (opt_ast) { @@ -191,9 +191,7 @@ int main(int argc, const char **argv) { auto ret = parser.parse_n(source.data(), source.size(), ast); if (ast) { - if (opt_optimize) { - ast = parser.optimize_ast(ast, opt_mode); - } + if (opt_optimize) { ast = parser.optimize_ast(ast, opt_mode); } std::cout << peg::ast_to_s(ast); } diff --git a/peglib.h b/peglib.h index 2d3280b..d225804 100644 --- a/peglib.h +++ b/peglib.h @@ -1745,29 +1745,56 @@ struct Ope::Visitor { virtual void visit(Cut &) {} }; -template -struct OpeType : public Ope::Visitor { +template struct OpeType : public Ope::Visitor { void visit(Sequence &) override { ret_ = std::is_same::value; } - void visit(PrioritizedChoice &) override { ret_ = std::is_same::value; } - void visit(Repetition &) override { ret_ = std::is_same::value; } - void visit(AndPredicate &) override { ret_ = std::is_same::value; } - void visit(NotPredicate &) override { ret_ = std::is_same::value; } - void visit(Dictionary &) override { ret_ = std::is_same::value; } - void visit(LiteralString &) override { ret_ = std::is_same::value; } - void visit(CharacterClass &) override { ret_ = std::is_same::value; } + void visit(PrioritizedChoice &) override { + ret_ = std::is_same::value; + } + void visit(Repetition &) override { + ret_ = std::is_same::value; + } + void visit(AndPredicate &) override { + ret_ = std::is_same::value; + } + void visit(NotPredicate &) override { + ret_ = std::is_same::value; + } + void visit(Dictionary &) override { + ret_ = std::is_same::value; + } + void visit(LiteralString &) override { + ret_ = std::is_same::value; + } + void visit(CharacterClass &) override { + ret_ = std::is_same::value; + } void visit(Character &) override { ret_ = std::is_same::value; } - void visit(AnyCharacter &) override { ret_ = std::is_same::value; } - void visit(CaptureScope &) override { ret_ = std::is_same::value; } + void visit(AnyCharacter &) override { + ret_ = std::is_same::value; + } + void visit(CaptureScope &) override { + ret_ = std::is_same::value; + } void visit(Capture &) override { ret_ = std::is_same::value; } - void visit(TokenBoundary &) override { ret_ = std::is_same::value; } + void visit(TokenBoundary &) override { + ret_ = std::is_same::value; + } void visit(Ignore &) override { ret_ = std::is_same::value; } void visit(User &) override { ret_ = std::is_same::value; } - void visit(WeakHolder &) override { ret_ = std::is_same::value; } + void visit(WeakHolder &) override { + ret_ = std::is_same::value; + } void visit(Holder &) override { ret_ = std::is_same::value; } void visit(Reference &) override { ret_ = std::is_same::value; } - void visit(Whitespace &) override { ret_ = std::is_same::value; } - void visit(BackReference &) override { ret_ = std::is_same::value; } - void visit(PrecedenceClimbing &) override { ret_ = std::is_same::value; } + void visit(Whitespace &) override { + ret_ = std::is_same::value; + } + void visit(BackReference &) override { + ret_ = std::is_same::value; + } + void visit(PrecedenceClimbing &) override { + ret_ = std::is_same::value; + } void visit(Recovery &) override { ret_ = std::is_same::value; } void visit(Cut &) override { ret_ = std::is_same::value; } @@ -2442,7 +2469,8 @@ private: if (whitespaceOpe) { auto save_ignore_trace_state = c.ignore_trace_state; c.ignore_trace_state = !c.tracer_verbose; - auto se = scope_exit([&]() { c.ignore_trace_state = save_ignore_trace_state; }); + auto se = + scope_exit([&]() { c.ignore_trace_state = save_ignore_trace_state; }); auto len = whitespaceOpe->parse(s, n, vs, c, dt); if (fail(len)) { @@ -2485,7 +2513,8 @@ inline size_t parse_literal(const char *s, size_t n, SemanticValues &vs, if (c.wordOpe) { auto save_ignore_trace_state = c.ignore_trace_state; c.ignore_trace_state = !c.tracer_verbose; - auto se = scope_exit([&]() { c.ignore_trace_state = save_ignore_trace_state; }); + auto se = + scope_exit([&]() { c.ignore_trace_state = save_ignore_trace_state; }); std::call_once(init_is_word, [&]() { SemanticValues dummy_vs; @@ -2516,7 +2545,8 @@ inline size_t parse_literal(const char *s, size_t n, SemanticValues &vs, if (c.whitespaceOpe) { auto save_ignore_trace_state = c.ignore_trace_state; c.ignore_trace_state = !c.tracer_verbose; - auto se = scope_exit([&]() { c.ignore_trace_state = save_ignore_trace_state; }); + auto se = + scope_exit([&]() { c.ignore_trace_state = save_ignore_trace_state; }); auto len = c.whitespaceOpe->parse(s + i, n - i, vs, c, dt); if (fail(len)) { return len; } @@ -2614,7 +2644,8 @@ inline size_t TokenBoundary::parse_core(const char *s, size_t n, std::any &dt) const { auto save_ignore_trace_state = c.ignore_trace_state; c.ignore_trace_state = !c.tracer_verbose; - auto se = scope_exit([&]() { c.ignore_trace_state = save_ignore_trace_state; }); + auto se = + scope_exit([&]() { c.ignore_trace_state = save_ignore_trace_state; }); size_t len; { @@ -2725,7 +2756,8 @@ inline size_t Reference::parse_core(const char *s, size_t n, SemanticValues &vs, if (rule_ && rule_->ignoreSemanticValue) { c.ignore_trace_state = !c.tracer_verbose; } - auto se = scope_exit([&]() { c.ignore_trace_state = save_ignore_trace_state; }); + auto se = + scope_exit([&]() { c.ignore_trace_state = save_ignore_trace_state; }); if (rule_) { // Reference rule @@ -3212,7 +3244,8 @@ private: // NOTE: This is different from The original Brian Ford's paper, and this // modification allows us to specify `[+-]` as a valid char class. - g["Range"] <= cho(seq(g["Char"], chr('-'), npd(chr(']')), g["Char"]), g["Char"]); + g["Range"] <= + cho(seq(g["Char"], chr('-'), npd(chr(']')), g["Char"]), g["Char"]); g["Char"] <= cho(seq(chr('\\'), cls("fnrtv'\"[]\\^")), @@ -3335,14 +3368,10 @@ private: if (is_macro) { params = std::any_cast>(vs[2]); ope = std::any_cast>(vs[4]); - if (vs.size() == 6) { - has_instructions = true; - } + if (vs.size() == 6) { has_instructions = true; } } else { ope = std::any_cast>(vs[3]); - if (vs.size() == 5) { - has_instructions = true; - } + if (vs.size() == 5) { has_instructions = true; } } if (has_instructions) { @@ -3355,8 +3384,10 @@ private: data.instructions[name].push_back(instruction); types.insert(instruction.type); } else { - // data.duplicates_of_instruction.emplace_back(type, vs.sv().data()); - data.duplicates_of_instruction.emplace_back(type, instruction.sv.data()); + // data.duplicates_of_instruction.emplace_back(type, + // vs.sv().data()); + data.duplicates_of_instruction.emplace_back(type, + instruction.sv.data()); } } } @@ -3668,7 +3699,7 @@ private: return instruction; }; - g["NoAstOpt"] = [](const SemanticValues & vs) { + g["NoAstOpt"] = [](const SemanticValues &vs) { Instruction instruction; instruction.type = "no_ast_opt"; instruction.sv = vs.sv(); @@ -3778,7 +3809,8 @@ private: for (const auto &[name, ptr] : data.duplicates_of_definition) { if (log) { auto line = line_info(s, ptr); - log(line.first, line.second, "The definition '" + name + "' is already defined."); + log(line.first, line.second, + "The definition '" + name + "' is already defined."); } } ret = false; @@ -3789,7 +3821,8 @@ private: for (const auto &[type, ptr] : data.duplicates_of_instruction) { if (log) { auto line = line_info(s, ptr); - log(line.first, line.second, "The instruction '" + type + "' is already defined."); + log(line.first, line.second, + "The instruction '" + type + "' is already defined."); } } ret = false; @@ -3871,9 +3904,7 @@ private: if (!ret) { return nullptr; } // Check infinite loop - if (detect_infiniteLoop(data, start_rule, log, s)) { - return nullptr; - } + if (detect_infiniteLoop(data, start_rule, log, s)) { return nullptr; } // Automatic whitespace skipping if (grammar.count(WHITESPACE_DEFINITION_NAME)) { @@ -3886,9 +3917,7 @@ private: auto &rule = grammar[WHITESPACE_DEFINITION_NAME]; start_rule.whitespaceOpe = wsp(rule.get_core_operator()); - if (detect_infiniteLoop(data, rule, log, s)) { - return nullptr; - } + if (detect_infiniteLoop(data, rule, log, s)) { return nullptr; } } // Word expression @@ -3896,16 +3925,14 @@ private: auto &rule = grammar[WORD_DEFINITION_NAME]; start_rule.wordOpe = rule.get_core_operator(); - if (detect_infiniteLoop(data, rule, log, s)) { - return nullptr; - } + if (detect_infiniteLoop(data, rule, log, s)) { return nullptr; } } // Apply instructions for (const auto &[name, instructions] : data.instructions) { auto &rule = grammar[name]; - for (const auto& instruction: instructions) { + for (const auto &instruction : instructions) { if (instruction.type == "precedence") { const auto &info = std::any_cast(instruction.data); @@ -3928,7 +3955,8 @@ private: return data.grammar; } - bool detect_infiniteLoop(const Data &data, Definition &rule, const Log &log, const char *s) const { + bool detect_infiniteLoop(const Data &data, Definition &rule, const Log &log, + const char *s) const { DetectInfiniteLoop vis(data.start_pos, rule.name); rule.accept(vis); if (vis.has_error) { @@ -4357,7 +4385,8 @@ public: } } - void enable_trace(TracerEnter tracer_enter, TracerLeave tracer_leave, bool tracer_verbose = false) { + void enable_trace(TracerEnter tracer_enter, TracerLeave tracer_leave, + bool tracer_verbose = false) { if (grammar_ != nullptr) { auto &rule = (*grammar_)[start_]; rule.tracer_enter = tracer_enter; diff --git a/test/test1.cc b/test/test1.cc index 4247dce..cce265d 100644 --- a/test/test1.cc +++ b/test/test1.cc @@ -324,9 +324,7 @@ TEST(GeneralTest, WHITESPACE_test4) { EXPECT_EQ("hello", vs.token()); }; - parser["OPE"] = [](const SemanticValues &vs) { - EXPECT_EQ("+", vs.token()); - }; + parser["OPE"] = [](const SemanticValues &vs) { EXPECT_EQ("+", vs.token()); }; parser["WORLD"] = [](const SemanticValues &vs) { EXPECT_EQ("world", vs.token()); @@ -355,9 +353,7 @@ TEST(GeneralTest, Skip_token_test) { " ITEM <- ([a-z0-9])+ " " ~_ <- [ \t]* "); - parser["ROOT"] = [&](const SemanticValues &vs) { - EXPECT_EQ(2, vs.size()); - }; + parser["ROOT"] = [&](const SemanticValues &vs) { EXPECT_EQ(2, vs.size()); }; auto ret = parser.parse(" item1, item2 "); @@ -371,9 +367,7 @@ TEST(GeneralTest, Skip_token_test2) { %whitespace <- [ \t]* )"); - parser["ROOT"] = [&](const SemanticValues &vs) { - EXPECT_EQ(2, vs.size()); - }; + parser["ROOT"] = [&](const SemanticValues &vs) { EXPECT_EQ(2, vs.size()); }; auto ret = parser.parse(" item1, item2 "); @@ -968,17 +962,17 @@ TEST(GeneralTest, token_to_number_float_test) { } TEST(GeneralTest, ParentReferencesShouldNotBeExpired) { - auto parser = peg::parser(R"( + auto parser = peg::parser(R"( ROOT <- OPTIMIZES_AWAY OPTIMIZES_AWAY <- ITEM+ ITEM <- 'a' )"); - parser.enable_ast(); + parser.enable_ast(); - std::shared_ptr ast; - parser.parse("aaa", ast); - ast = parser.optimize_ast(ast); + std::shared_ptr ast; + parser.parse("aaa", ast); + ast = parser.optimize_ast(ast); - EXPECT_FALSE(ast->nodes[0]->parent.expired()); + EXPECT_FALSE(ast->nodes[0]->parent.expired()); } diff --git a/test/test2.cc b/test/test2.cc index ba365de..a471a7b 100644 --- a/test/test2.cc +++ b/test/test2.cc @@ -1278,7 +1278,7 @@ TEST(ErrorTest, Default_error_handling_fiblang) { EXPECT_TRUE(!!pg); std::vector errors{ - R"(4:7: syntax error, unexpected 'frm', expecting 'from'.)", + R"(4:7: syntax error, unexpected 'frm', expecting 'from'.)", }; size_t i = 0; @@ -1418,7 +1418,8 @@ rrr | sss + ENTRY/1 - PHRASE/0[WORD] (rrr) - PHRASE/0[WORD] (sss) -)", ast_to_s(ast)); +)", + ast_to_s(ast)); } TEST(ErrorTest, Error_recovery_2) { @@ -1480,7 +1481,6 @@ TEST(ErrorTest, Error_recovery_2) { ast_to_s(ast)); } - TEST(ErrorTest, Error_recovery_3) { parser pg(R"~( # Grammar @@ -1689,7 +1689,8 @@ sss | ttt - WORD (sss) + PHRASE - WORD (ttt) -)", ast_to_s(ast)); +)", + ast_to_s(ast)); } TEST(ErrorTest, Error_recovery_Java) { diff --git a/test/test3.cc b/test/test3.cc index 56701ad..f644f2f 100644 --- a/test/test3.cc +++ b/test/test3.cc @@ -152,8 +152,9 @@ TEST(LeftRecursiveTest, PEG_Literal) { TEST(LeftRecursiveTest, PEG_Class) { auto g = ParserGenerator::grammar(); - EXPECT_FALSE(exact(g, "Class", "[]")); // NOTE: This is different from the Brian Ford's paper, but - // same as RegExp + EXPECT_FALSE( + exact(g, "Class", "[]")); // NOTE: This is different from the Brian Ford's + // paper, but same as RegExp EXPECT_TRUE(exact(g, "Class", "[a]")); EXPECT_TRUE(exact(g, "Class", "[a-z]")); EXPECT_TRUE(exact(g, "Class", "[az]"));