Code format

This commit is contained in:
yhirose 2022-05-27 21:50:27 -04:00
parent 959128ec0f
commit 9768721b2b
6 changed files with 97 additions and 74 deletions

Binary file not shown.

View File

@ -124,9 +124,7 @@ int main(int argc, const char **argv) {
cerr << source_path << ":" << ln << ":" << col << ": " << msg << endl; cerr << source_path << ":" << ln << ":" << col << ": " << msg << endl;
}; };
if (opt_packrat) { if (opt_packrat) { parser.enable_packrat_parsing(); }
parser.enable_packrat_parsing();
}
if (opt_trace) { if (opt_trace) {
size_t prev_pos = 0; size_t prev_pos = 0;
@ -180,8 +178,10 @@ int main(int argc, const char **argv) {
matched = ", match '" + peg::escape_characters(s, len) + "'"; matched = ", match '" + peg::escape_characters(s, len) + "'";
} }
std::cout << "L " << pos << "\t" << indent << ret << name << " #" std::cout << "L " << pos << "\t" << indent << ret << name << " #"
<< c.trace_ids.back() << choice.str() << token << matched << std::endl; << c.trace_ids.back() << choice.str() << token << matched
}, opt_verbose); << std::endl;
},
opt_verbose);
} }
if (opt_ast) { if (opt_ast) {
@ -191,9 +191,7 @@ int main(int argc, const char **argv) {
auto ret = parser.parse_n(source.data(), source.size(), ast); auto ret = parser.parse_n(source.data(), source.size(), ast);
if (ast) { if (ast) {
if (opt_optimize) { if (opt_optimize) { ast = parser.optimize_ast(ast, opt_mode); }
ast = parser.optimize_ast(ast, opt_mode);
}
std::cout << peg::ast_to_s(ast); std::cout << peg::ast_to_s(ast);
} }

119
peglib.h
View File

@ -1745,29 +1745,56 @@ struct Ope::Visitor {
virtual void visit(Cut &) {} virtual void visit(Cut &) {}
}; };
template <typename T> template <typename T> struct OpeType : public Ope::Visitor {
struct OpeType : public Ope::Visitor {
void visit(Sequence &) override { ret_ = std::is_same<Sequence, T>::value; } void visit(Sequence &) override { ret_ = std::is_same<Sequence, T>::value; }
void visit(PrioritizedChoice &) override { ret_ = std::is_same<PrioritizedChoice, T>::value; } void visit(PrioritizedChoice &) override {
void visit(Repetition &) override { ret_ = std::is_same<Repetition, T>::value; } ret_ = std::is_same<PrioritizedChoice, T>::value;
void visit(AndPredicate &) override { ret_ = std::is_same<AndPredicate, T>::value; } }
void visit(NotPredicate &) override { ret_ = std::is_same<NotPredicate, T>::value; } void visit(Repetition &) override {
void visit(Dictionary &) override { ret_ = std::is_same<Dictionary, T>::value; } ret_ = std::is_same<Repetition, T>::value;
void visit(LiteralString &) override { ret_ = std::is_same<LiteralString, T>::value; } }
void visit(CharacterClass &) override { ret_ = std::is_same<CharacterClass, T>::value; } void visit(AndPredicate &) override {
ret_ = std::is_same<AndPredicate, T>::value;
}
void visit(NotPredicate &) override {
ret_ = std::is_same<NotPredicate, T>::value;
}
void visit(Dictionary &) override {
ret_ = std::is_same<Dictionary, T>::value;
}
void visit(LiteralString &) override {
ret_ = std::is_same<LiteralString, T>::value;
}
void visit(CharacterClass &) override {
ret_ = std::is_same<CharacterClass, T>::value;
}
void visit(Character &) override { ret_ = std::is_same<Character, T>::value; } void visit(Character &) override { ret_ = std::is_same<Character, T>::value; }
void visit(AnyCharacter &) override { ret_ = std::is_same<AnyCharacter, T>::value; } void visit(AnyCharacter &) override {
void visit(CaptureScope &) override { ret_ = std::is_same<CaptureScope, T>::value; } ret_ = std::is_same<AnyCharacter, T>::value;
}
void visit(CaptureScope &) override {
ret_ = std::is_same<CaptureScope, T>::value;
}
void visit(Capture &) override { ret_ = std::is_same<Capture, T>::value; } void visit(Capture &) override { ret_ = std::is_same<Capture, T>::value; }
void visit(TokenBoundary &) override { ret_ = std::is_same<TokenBoundary, T>::value; } void visit(TokenBoundary &) override {
ret_ = std::is_same<TokenBoundary, T>::value;
}
void visit(Ignore &) override { ret_ = std::is_same<Ignore, T>::value; } void visit(Ignore &) override { ret_ = std::is_same<Ignore, T>::value; }
void visit(User &) override { ret_ = std::is_same<User, T>::value; } void visit(User &) override { ret_ = std::is_same<User, T>::value; }
void visit(WeakHolder &) override { ret_ = std::is_same<WeakHolder, T>::value; } void visit(WeakHolder &) override {
ret_ = std::is_same<WeakHolder, T>::value;
}
void visit(Holder &) override { ret_ = std::is_same<Holder, T>::value; } void visit(Holder &) override { ret_ = std::is_same<Holder, T>::value; }
void visit(Reference &) override { ret_ = std::is_same<Reference, T>::value; } void visit(Reference &) override { ret_ = std::is_same<Reference, T>::value; }
void visit(Whitespace &) override { ret_ = std::is_same<Whitespace, T>::value; } void visit(Whitespace &) override {
void visit(BackReference &) override { ret_ = std::is_same<BackReference, T>::value; } ret_ = std::is_same<Whitespace, T>::value;
void visit(PrecedenceClimbing &) override { ret_ = std::is_same<PrecedenceClimbing, T>::value; } }
void visit(BackReference &) override {
ret_ = std::is_same<BackReference, T>::value;
}
void visit(PrecedenceClimbing &) override {
ret_ = std::is_same<PrecedenceClimbing, T>::value;
}
void visit(Recovery &) override { ret_ = std::is_same<Recovery, T>::value; } void visit(Recovery &) override { ret_ = std::is_same<Recovery, T>::value; }
void visit(Cut &) override { ret_ = std::is_same<Cut, T>::value; } void visit(Cut &) override { ret_ = std::is_same<Cut, T>::value; }
@ -2442,7 +2469,8 @@ private:
if (whitespaceOpe) { if (whitespaceOpe) {
auto save_ignore_trace_state = c.ignore_trace_state; auto save_ignore_trace_state = c.ignore_trace_state;
c.ignore_trace_state = !c.tracer_verbose; 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); auto len = whitespaceOpe->parse(s, n, vs, c, dt);
if (fail(len)) { if (fail(len)) {
@ -2485,7 +2513,8 @@ inline size_t parse_literal(const char *s, size_t n, SemanticValues &vs,
if (c.wordOpe) { if (c.wordOpe) {
auto save_ignore_trace_state = c.ignore_trace_state; auto save_ignore_trace_state = c.ignore_trace_state;
c.ignore_trace_state = !c.tracer_verbose; 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, [&]() { std::call_once(init_is_word, [&]() {
SemanticValues dummy_vs; SemanticValues dummy_vs;
@ -2516,7 +2545,8 @@ inline size_t parse_literal(const char *s, size_t n, SemanticValues &vs,
if (c.whitespaceOpe) { if (c.whitespaceOpe) {
auto save_ignore_trace_state = c.ignore_trace_state; auto save_ignore_trace_state = c.ignore_trace_state;
c.ignore_trace_state = !c.tracer_verbose; 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); auto len = c.whitespaceOpe->parse(s + i, n - i, vs, c, dt);
if (fail(len)) { return len; } 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 { std::any &dt) const {
auto save_ignore_trace_state = c.ignore_trace_state; auto save_ignore_trace_state = c.ignore_trace_state;
c.ignore_trace_state = !c.tracer_verbose; 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; 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) { if (rule_ && rule_->ignoreSemanticValue) {
c.ignore_trace_state = !c.tracer_verbose; 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_) { if (rule_) {
// Reference rule // Reference rule
@ -3212,7 +3244,8 @@ private:
// NOTE: This is different from The original Brian Ford's paper, and this // NOTE: This is different from The original Brian Ford's paper, and this
// modification allows us to specify `[+-]` as a valid char class. // 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"] <= g["Char"] <=
cho(seq(chr('\\'), cls("fnrtv'\"[]\\^")), cho(seq(chr('\\'), cls("fnrtv'\"[]\\^")),
@ -3335,14 +3368,10 @@ private:
if (is_macro) { if (is_macro) {
params = std::any_cast<std::vector<std::string>>(vs[2]); params = std::any_cast<std::vector<std::string>>(vs[2]);
ope = std::any_cast<std::shared_ptr<Ope>>(vs[4]); ope = std::any_cast<std::shared_ptr<Ope>>(vs[4]);
if (vs.size() == 6) { if (vs.size() == 6) { has_instructions = true; }
has_instructions = true;
}
} else { } else {
ope = std::any_cast<std::shared_ptr<Ope>>(vs[3]); ope = std::any_cast<std::shared_ptr<Ope>>(vs[3]);
if (vs.size() == 5) { if (vs.size() == 5) { has_instructions = true; }
has_instructions = true;
}
} }
if (has_instructions) { if (has_instructions) {
@ -3355,8 +3384,10 @@ private:
data.instructions[name].push_back(instruction); data.instructions[name].push_back(instruction);
types.insert(instruction.type); types.insert(instruction.type);
} else { } else {
// data.duplicates_of_instruction.emplace_back(type, vs.sv().data()); // data.duplicates_of_instruction.emplace_back(type,
data.duplicates_of_instruction.emplace_back(type, instruction.sv.data()); // vs.sv().data());
data.duplicates_of_instruction.emplace_back(type,
instruction.sv.data());
} }
} }
} }
@ -3668,7 +3699,7 @@ private:
return instruction; return instruction;
}; };
g["NoAstOpt"] = [](const SemanticValues & vs) { g["NoAstOpt"] = [](const SemanticValues &vs) {
Instruction instruction; Instruction instruction;
instruction.type = "no_ast_opt"; instruction.type = "no_ast_opt";
instruction.sv = vs.sv(); instruction.sv = vs.sv();
@ -3778,7 +3809,8 @@ private:
for (const auto &[name, ptr] : data.duplicates_of_definition) { for (const auto &[name, ptr] : data.duplicates_of_definition) {
if (log) { if (log) {
auto line = line_info(s, ptr); 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; ret = false;
@ -3789,7 +3821,8 @@ private:
for (const auto &[type, ptr] : data.duplicates_of_instruction) { for (const auto &[type, ptr] : data.duplicates_of_instruction) {
if (log) { if (log) {
auto line = line_info(s, ptr); 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; ret = false;
@ -3871,9 +3904,7 @@ private:
if (!ret) { return nullptr; } if (!ret) { return nullptr; }
// Check infinite loop // Check infinite loop
if (detect_infiniteLoop(data, start_rule, log, s)) { if (detect_infiniteLoop(data, start_rule, log, s)) { return nullptr; }
return nullptr;
}
// Automatic whitespace skipping // Automatic whitespace skipping
if (grammar.count(WHITESPACE_DEFINITION_NAME)) { if (grammar.count(WHITESPACE_DEFINITION_NAME)) {
@ -3886,9 +3917,7 @@ private:
auto &rule = grammar[WHITESPACE_DEFINITION_NAME]; auto &rule = grammar[WHITESPACE_DEFINITION_NAME];
start_rule.whitespaceOpe = wsp(rule.get_core_operator()); start_rule.whitespaceOpe = wsp(rule.get_core_operator());
if (detect_infiniteLoop(data, rule, log, s)) { if (detect_infiniteLoop(data, rule, log, s)) { return nullptr; }
return nullptr;
}
} }
// Word expression // Word expression
@ -3896,16 +3925,14 @@ private:
auto &rule = grammar[WORD_DEFINITION_NAME]; auto &rule = grammar[WORD_DEFINITION_NAME];
start_rule.wordOpe = rule.get_core_operator(); start_rule.wordOpe = rule.get_core_operator();
if (detect_infiniteLoop(data, rule, log, s)) { if (detect_infiniteLoop(data, rule, log, s)) { return nullptr; }
return nullptr;
}
} }
// Apply instructions // Apply instructions
for (const auto &[name, instructions] : data.instructions) { for (const auto &[name, instructions] : data.instructions) {
auto &rule = grammar[name]; auto &rule = grammar[name];
for (const auto& instruction: instructions) { for (const auto &instruction : instructions) {
if (instruction.type == "precedence") { if (instruction.type == "precedence") {
const auto &info = const auto &info =
std::any_cast<PrecedenceClimbing::BinOpeInfo>(instruction.data); std::any_cast<PrecedenceClimbing::BinOpeInfo>(instruction.data);
@ -3928,7 +3955,8 @@ private:
return data.grammar; 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); DetectInfiniteLoop vis(data.start_pos, rule.name);
rule.accept(vis); rule.accept(vis);
if (vis.has_error) { 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) { if (grammar_ != nullptr) {
auto &rule = (*grammar_)[start_]; auto &rule = (*grammar_)[start_];
rule.tracer_enter = tracer_enter; rule.tracer_enter = tracer_enter;

View File

@ -324,9 +324,7 @@ TEST(GeneralTest, WHITESPACE_test4) {
EXPECT_EQ("hello", vs.token()); EXPECT_EQ("hello", vs.token());
}; };
parser["OPE"] = [](const SemanticValues &vs) { parser["OPE"] = [](const SemanticValues &vs) { EXPECT_EQ("+", vs.token()); };
EXPECT_EQ("+", vs.token());
};
parser["WORLD"] = [](const SemanticValues &vs) { parser["WORLD"] = [](const SemanticValues &vs) {
EXPECT_EQ("world", vs.token()); EXPECT_EQ("world", vs.token());
@ -355,9 +353,7 @@ TEST(GeneralTest, Skip_token_test) {
" ITEM <- ([a-z0-9])+ " " ITEM <- ([a-z0-9])+ "
" ~_ <- [ \t]* "); " ~_ <- [ \t]* ");
parser["ROOT"] = [&](const SemanticValues &vs) { parser["ROOT"] = [&](const SemanticValues &vs) { EXPECT_EQ(2, vs.size()); };
EXPECT_EQ(2, vs.size());
};
auto ret = parser.parse(" item1, item2 "); auto ret = parser.parse(" item1, item2 ");
@ -371,9 +367,7 @@ TEST(GeneralTest, Skip_token_test2) {
%whitespace <- [ \t]* %whitespace <- [ \t]*
)"); )");
parser["ROOT"] = [&](const SemanticValues &vs) { parser["ROOT"] = [&](const SemanticValues &vs) { EXPECT_EQ(2, vs.size()); };
EXPECT_EQ(2, vs.size());
};
auto ret = parser.parse(" item1, item2 "); auto ret = parser.parse(" item1, item2 ");
@ -968,17 +962,17 @@ TEST(GeneralTest, token_to_number_float_test) {
} }
TEST(GeneralTest, ParentReferencesShouldNotBeExpired) { TEST(GeneralTest, ParentReferencesShouldNotBeExpired) {
auto parser = peg::parser(R"( auto parser = peg::parser(R"(
ROOT <- OPTIMIZES_AWAY ROOT <- OPTIMIZES_AWAY
OPTIMIZES_AWAY <- ITEM+ OPTIMIZES_AWAY <- ITEM+
ITEM <- 'a' ITEM <- 'a'
)"); )");
parser.enable_ast<peg::Ast>(); parser.enable_ast<peg::Ast>();
std::shared_ptr<peg::Ast> ast; std::shared_ptr<peg::Ast> ast;
parser.parse("aaa", ast); parser.parse("aaa", ast);
ast = parser.optimize_ast(ast); ast = parser.optimize_ast(ast);
EXPECT_FALSE(ast->nodes[0]->parent.expired()); EXPECT_FALSE(ast->nodes[0]->parent.expired());
} }

View File

@ -1278,7 +1278,7 @@ TEST(ErrorTest, Default_error_handling_fiblang) {
EXPECT_TRUE(!!pg); EXPECT_TRUE(!!pg);
std::vector<std::string> errors{ std::vector<std::string> errors{
R"(4:7: syntax error, unexpected 'frm', expecting 'from'.)", R"(4:7: syntax error, unexpected 'frm', expecting 'from'.)",
}; };
size_t i = 0; size_t i = 0;
@ -1418,7 +1418,8 @@ rrr | sss
+ ENTRY/1 + ENTRY/1
- PHRASE/0[WORD] (rrr) - PHRASE/0[WORD] (rrr)
- PHRASE/0[WORD] (sss) - PHRASE/0[WORD] (sss)
)", ast_to_s(ast)); )",
ast_to_s(ast));
} }
TEST(ErrorTest, Error_recovery_2) { TEST(ErrorTest, Error_recovery_2) {
@ -1480,7 +1481,6 @@ TEST(ErrorTest, Error_recovery_2) {
ast_to_s(ast)); ast_to_s(ast));
} }
TEST(ErrorTest, Error_recovery_3) { TEST(ErrorTest, Error_recovery_3) {
parser pg(R"~( parser pg(R"~(
# Grammar # Grammar
@ -1689,7 +1689,8 @@ sss | ttt
- WORD (sss) - WORD (sss)
+ PHRASE + PHRASE
- WORD (ttt) - WORD (ttt)
)", ast_to_s(ast)); )",
ast_to_s(ast));
} }
TEST(ErrorTest, Error_recovery_Java) { TEST(ErrorTest, Error_recovery_Java) {

View File

@ -152,8 +152,9 @@ TEST(LeftRecursiveTest, PEG_Literal) {
TEST(LeftRecursiveTest, PEG_Class) { TEST(LeftRecursiveTest, PEG_Class) {
auto g = ParserGenerator::grammar(); auto g = ParserGenerator::grammar();
EXPECT_FALSE(exact(g, "Class", "[]")); // NOTE: This is different from the Brian Ford's paper, but EXPECT_FALSE(
// same as RegExp 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]"));
EXPECT_TRUE(exact(g, "Class", "[a-z]")); EXPECT_TRUE(exact(g, "Class", "[a-z]"));
EXPECT_TRUE(exact(g, "Class", "[az]")); EXPECT_TRUE(exact(g, "Class", "[az]"));