From d38aa596e16c166a284de7f4fca4a91508cb8aed Mon Sep 17 00:00:00 2001 From: Amaan Qureshi Date: Fri, 10 Jan 2025 02:23:24 -0500 Subject: [PATCH] fix(generate): improve error message when a duplicate token is used as the word token --- cli/generate/src/prepare_grammar/extract_tokens.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/cli/generate/src/prepare_grammar/extract_tokens.rs b/cli/generate/src/prepare_grammar/extract_tokens.rs index 6a0ebc0e..daa034b3 100644 --- a/cli/generate/src/prepare_grammar/extract_tokens.rs +++ b/cli/generate/src/prepare_grammar/extract_tokens.rs @@ -26,8 +26,8 @@ unless they are used only as the grammar's start rule. ExternalTokenNonTerminal(String), #[error("Non-symbol rules cannot be used as external tokens")] NonSymbolExternalToken, - #[error("Non-terminal symbol '{0}' cannot be used as the word token")] - NonTerminalWordToken(String), + #[error("Non-terminal symbol '{0}' cannot be used as the word token, because its rule is duplicated in '{1}'")] + NonTerminalWordToken(String, String), #[error("Reserved words must be tokens")] NonTokenReservedWord, } @@ -161,8 +161,16 @@ pub(super) fn extract_tokens( if let Some(token) = grammar.word_token { let token = symbol_replacer.replace_symbol(token); if token.is_non_terminal() { + let word_token_variable = &variables[token.index]; + let conflicting_variable = variables + .iter() + .enumerate() + .find(|(i, v)| *i != token.index && v.rule == word_token_variable.rule) + .expect("Failed to find a variable with the same rule as the word token"); + Err(ExtractTokensError::NonTerminalWordToken( - variables[token.index].name.clone(), + word_token_variable.name.clone(), + conflicting_variable.1.name.clone(), ))?; } word_token = Some(token);