fix(generate): warn users when extra rule can lead to parser hang

When a *named* rule in the extras is able to match the empty string,
parsing can hang in certain situations (i.e. near EOF).

(cherry picked from commit ac171eb280)
This commit is contained in:
Will Lillis 2025-08-29 02:57:37 -04:00
parent e61407cc36
commit 253003ccf8

View file

@ -1,6 +1,7 @@
use std::collections::HashSet;
use anyhow::Result;
use regex::Regex;
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
use thiserror::Error;
@ -262,6 +263,27 @@ pub(crate) fn parse_grammar(input: &str) -> ParseGrammarResult<InputGrammar> {
});
continue;
}
if extra_symbols
.iter()
.any(|r| rule_is_referenced(r, name, false))
{
let inner_rule = if let Rule::Metadata { rule, .. } = rule {
rule
} else {
rule
};
let matches_empty = match inner_rule {
Rule::String(rule_str) => rule_str.is_empty(),
Rule::Pattern(ref value, _) => Regex::new(value)
.map(|reg| reg.is_match(""))
.unwrap_or(false),
_ => false,
};
if matches_empty {
eprintln!("Warning: Named extra rule `{name}` matches the empty string. Inline this to avoid infinite loops while parsing.");
}
}
variables.push(Variable {
name: name.clone(),
kind: VariableType::Named,