feat(generate): explicitly disallow non-terminals in non-terminals

This commit is contained in:
Amaan Qureshi 2025-01-12 03:14:54 -05:00
parent d65a74a667
commit 9d9c76e693
2 changed files with 11 additions and 1 deletions

View file

@ -72,6 +72,10 @@ pub enum ParseTableBuilderError {
Conflict(#[from] ConflictError),
#[error("Extra rules must have unambiguous endings. Conflicting rules: {0}")]
AmbiguousExtra(#[from] AmbiguousExtraError),
#[error(
"The non-terminal rule `{0}` is used in a non-terminal `extra` rule, which is not allowed."
)]
ImproperNonTerminalExtra(String),
}
#[derive(Default, Debug, Serialize)]
@ -310,6 +314,12 @@ impl<'a> ParseTableBuilder<'a> {
// Add a state for each starting terminal of a non-terminal extra rule.
for (terminal, item_set) in non_terminal_extra_item_sets_by_first_terminal {
if terminal.is_non_terminal() {
Err(ParseTableBuilderError::ImproperNonTerminalExtra(
self.symbol_name(&terminal),
))?;
}
self.non_terminal_extra_states
.push((terminal, self.parse_table.states.len()));
self.add_parse_state(&Vec::new(), &Vec::new(), item_set);

View file

@ -749,7 +749,7 @@ impl Generate {
std::process::exit(1);
} else {
// Removes extra context associated with the error
Err(anyhow!(err.to_string()))?;
Err(anyhow!(err.to_string())).with_context(|| "Error when generating parser")?;
}
}
if self.build {