This commit is contained in:
yhirose 2022-05-26 21:37:08 -04:00
parent 7ee4fccb95
commit 3c745bf581
3 changed files with 47 additions and 14 deletions

Binary file not shown.

View File

@ -3810,17 +3810,8 @@ private:
if (!ret) { return nullptr; } if (!ret) { return nullptr; }
// Check infinite loop // Check infinite loop
{ if (detect_infiniteLoop(data, start_rule, log, s)) {
DetectInfiniteLoop vis(data.start_pos, data.start); return nullptr;
start_rule.accept(vis);
if (vis.has_error) {
if (log) {
auto line = line_info(s, vis.error_s);
log(line.first, line.second,
"infinite loop is detected in '" + vis.error_name + "'.");
}
return nullptr;
}
} }
// Automatic whitespace skipping // Automatic whitespace skipping
@ -3831,13 +3822,22 @@ private:
if (IsLiteralToken::check(*ope)) { rule <= tok(ope); } if (IsLiteralToken::check(*ope)) { rule <= tok(ope); }
} }
start_rule.whitespaceOpe = auto &rule = grammar[WHITESPACE_DEFINITION_NAME];
wsp(grammar[WHITESPACE_DEFINITION_NAME].get_core_operator()); start_rule.whitespaceOpe = wsp(rule.get_core_operator());
if (detect_infiniteLoop(data, rule, log, s)) {
return nullptr;
}
} }
// Word expression // Word expression
if (grammar.count(WORD_DEFINITION_NAME)) { if (grammar.count(WORD_DEFINITION_NAME)) {
start_rule.wordOpe = grammar[WORD_DEFINITION_NAME].get_core_operator(); auto &rule = grammar[WORD_DEFINITION_NAME];
start_rule.wordOpe = rule.get_core_operator();
if (detect_infiniteLoop(data, rule, log, s)) {
return nullptr;
}
} }
// Apply instructions // Apply instructions
@ -3867,6 +3867,20 @@ private:
return data.grammar; return data.grammar;
} }
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) {
if (log) {
auto line = line_info(s, vis.error_s);
log(line.first, line.second,
"infinite loop is detected in '" + vis.error_name + "'.");
}
return true;
}
return false;
}
Grammar g; Grammar g;
}; };

View File

@ -204,6 +204,25 @@ TEST(InfiniteLoopTest, Not_infinite_3) {
EXPECT_TRUE(!!pg); EXPECT_TRUE(!!pg);
} }
TEST(InfiniteLoopTest, whitespace) {
parser pg(R"(
S <- 'hello'
%whitespace <- ('')*
)");
EXPECT_FALSE(pg);
}
TEST(InfiniteLoopTest, word) {
parser pg(R"(
S <- 'hello'
%whitespace <- ' '*
%word <- ('')*
)");
EXPECT_FALSE(pg);
}
TEST(PrecedenceTest, Precedence_climbing) { TEST(PrecedenceTest, Precedence_climbing) {
parser parser(R"( parser parser(R"(
START <- _ EXPRESSION START <- _ EXPRESSION