mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2024-12-22 11:55:30 +00:00
Fix #205
This commit is contained in:
parent
7ee4fccb95
commit
3c745bf581
BIN
docs/native.wasm
BIN
docs/native.wasm
Binary file not shown.
40
peglib.h
40
peglib.h
@ -3810,18 +3810,9 @@ private:
|
||||
if (!ret) { return nullptr; }
|
||||
|
||||
// Check infinite loop
|
||||
{
|
||||
DetectInfiniteLoop vis(data.start_pos, data.start);
|
||||
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 + "'.");
|
||||
}
|
||||
if (detect_infiniteLoop(data, start_rule, log, s)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Automatic whitespace skipping
|
||||
if (grammar.count(WHITESPACE_DEFINITION_NAME)) {
|
||||
@ -3831,13 +3822,22 @@ private:
|
||||
if (IsLiteralToken::check(*ope)) { rule <= tok(ope); }
|
||||
}
|
||||
|
||||
start_rule.whitespaceOpe =
|
||||
wsp(grammar[WHITESPACE_DEFINITION_NAME].get_core_operator());
|
||||
auto &rule = grammar[WHITESPACE_DEFINITION_NAME];
|
||||
start_rule.whitespaceOpe = wsp(rule.get_core_operator());
|
||||
|
||||
if (detect_infiniteLoop(data, rule, log, s)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Word expression
|
||||
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
|
||||
@ -3867,6 +3867,20 @@ private:
|
||||
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;
|
||||
};
|
||||
|
||||
|
@ -204,6 +204,25 @@ TEST(InfiniteLoopTest, Not_infinite_3) {
|
||||
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) {
|
||||
parser parser(R"(
|
||||
START <- _ EXPRESSION
|
||||
|
Loading…
Reference in New Issue
Block a user