From 1f010ad1aad8202828ab437ecaf1a635adda3c3f Mon Sep 17 00:00:00 2001 From: JSDurand Date: Fri, 21 Jul 2023 16:19:04 +0800 Subject: abnf: Correct error reports Previously the errors emitted while reading abnf grammars reported incorrect indices. Now this is fixed. --- grammar/src/abnf/mod.rs | 68 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 12 deletions(-) diff --git a/grammar/src/abnf/mod.rs b/grammar/src/abnf/mod.rs index 561a397..b53dcc1 100644 --- a/grammar/src/abnf/mod.rs +++ b/grammar/src/abnf/mod.rs @@ -89,6 +89,33 @@ pub enum Error { Invalid, } +impl Error { + fn translate(self, offset: usize) -> Self { + match self { + Error::HangingRuleName(offseta) => Error::HangingRuleName(offseta + offset), + Error::MinGreaterThanMax(offseta) => Error::MinGreaterThanMax(offseta + offset), + Error::InvalidDigit(offseta) => Error::InvalidDigit(offseta + offset), + Error::InvalidCharacter(offseta) => Error::InvalidCharacter(offseta + offset), + Error::HangingNumeric(offseta) => Error::HangingNumeric(offseta + offset), + Error::HangingRepetition(offseta) => Error::HangingRepetition(offseta + offset), + Error::HangingDQuote(offseta) => Error::HangingDQuote(offseta + offset), + Error::HangingPercent(offseta) => Error::HangingPercent(offseta + offset), + Error::HangingEqualsSign(offseta) => Error::HangingEqualsSign(offseta + offset), + Error::RegexEmptyStack(offseta) => Error::RegexEmptyStack(offseta + offset), + Error::RegexEmptyActionStack(offseta) => Error::RegexEmptyActionStack(offseta + offset), + Error::RegexUnbalancedParen(offseta) => Error::RegexUnbalancedParen(offseta + offset), + Error::RegexInvalidRepeat(offseta) => Error::RegexInvalidRepeat(offseta + offset), + Error::RegexInvalidComment(offseta) => Error::RegexInvalidComment(offseta + offset), + Error::RegexInvalidNumeric(offseta) => Error::RegexInvalidNumeric(offseta + offset), + Error::MissingEqualSign(offseta) => Error::MissingEqualSign(offseta + offset), + Error::Unimplemented(offseta) => Error::Unimplemented(offseta + offset), + Error::AppendToNothing(offseta) => Error::AppendToNothing(offseta + offset), + Error::CreateAgain(offseta) => Error::CreateAgain(offseta + offset), + _ => self, + } + } +} + impl std::error::Error for Error {} impl From for Error { @@ -619,7 +646,9 @@ fn parse_alternation(s: &str, indentation: usize) -> Result<(usize, AlternationC let nt_index = intermediates.len() - 1; - let action = repetition_spec.try_into()?; + let action = repetition_spec + .try_into() + .map_err(|e: Error| e.translate(current_index))?; // println!("rep_action = {action:?}"); let stack_last = stack @@ -848,7 +877,9 @@ fn parse_alternation(s: &str, indentation: usize) -> Result<(usize, AlternationC s = &s[1..]; current_index += 1; - let action = repetition_spec.try_into()?; + let action = repetition_spec + .try_into() + .map_err(|e: Error| e.translate(current_index))?; let stack_last = stack .iter() @@ -1229,7 +1260,9 @@ fn parse_alternation(s: &str, indentation: usize) -> Result<(usize, AlternationC '[' => { // option - let action = repetition_spec.try_into()?; + let action = repetition_spec + .try_into() + .map_err(|e: Error| e.translate(current_index))?; let stack_last = stack .iter() @@ -1678,7 +1711,9 @@ fn parse_alternation(s: &str, indentation: usize) -> Result<(usize, AlternationC return Err(Error::HangingDQuote(current_index)); } - let action = repetition_spec.try_into()?; + let action = repetition_spec + .try_into() + .map_err(|e: Error| e.translate(current_index))?; let stack_last = stack .iter() @@ -1826,7 +1861,8 @@ fn parse_alternation(s: &str, indentation: usize) -> Result<(usize, AlternationC s = &s[1..]; current_index += 1; - let (parsed_size, parsed_construct) = parse_numeric(s, Radix::Binary)?; + let (parsed_size, parsed_construct) = parse_numeric(s, Radix::Binary) + .map_err(|e| e.translate(current_index))?; intermediate_value = parsed_construct; @@ -1837,7 +1873,8 @@ fn parse_alternation(s: &str, indentation: usize) -> Result<(usize, AlternationC s = &s[1..]; current_index += 1; - let (parsed_size, parsed_construct) = parse_numeric(s, Radix::Decimal)?; + let (parsed_size, parsed_construct) = parse_numeric(s, Radix::Decimal) + .map_err(|e| e.translate(current_index))?; intermediate_value = parsed_construct; @@ -1848,7 +1885,8 @@ fn parse_alternation(s: &str, indentation: usize) -> Result<(usize, AlternationC s = &s[1..]; current_index += 1; - let (parsed_size, parsed_construct) = parse_numeric(s, Radix::Hexadecimal)?; + let (parsed_size, parsed_construct) = parse_numeric(s, Radix::Hexadecimal) + .map_err(|e| e.translate(current_index))?; // println!("size = {parsed_size}, construct = {parsed_construct:#?}"); intermediate_value = parsed_construct; @@ -1861,7 +1899,9 @@ fn parse_alternation(s: &str, indentation: usize) -> Result<(usize, AlternationC } } - let action = repetition_spec.try_into()?; + let action = repetition_spec + .try_into() + .map_err(|e: Error| e.translate(current_index))?; let stack_last = stack .iter() @@ -2265,7 +2305,8 @@ fn parse_one_rule(s: &str, indentation: usize) -> Result<(usize, RuleConstruct), // alternation - let (alternation_size, alternation_result) = parse_alternation(s, indentation)?; + let (alternation_size, alternation_result) = + parse_alternation(s, indentation).map_err(|e| e.translate(current_index))?; let intermediates_data = alternation_result.intermediates; let regex = alternation_result.regex; @@ -2391,7 +2432,8 @@ impl std::str::FromStr for Grammar { // First collect non-terminals in the order they are defined. loop { let (rule_size, (rule_name, _rule_data, _rule_regex, appending_p)) = - parse_one_rule(temp, basic_indentation)?; + parse_one_rule(temp, basic_indentation) + .map_err(|e| e.translate(current_skipped_index))?; if rule_size == 0 { break; @@ -2403,8 +2445,10 @@ impl std::str::FromStr for Grammar { return Err(Error::CreateAgain(current_skipped_index)); } - nonterminals_map.insert(rule_name.clone(), nonterminals_vec.len()); - nonterminals_vec.push(rule_name); + if !appending_p { + nonterminals_map.insert(rule_name.clone(), nonterminals_vec.len()); + nonterminals_vec.push(rule_name); + } if rule_size > 0 && rule_size < temp.len() { temp = &temp[rule_size..]; -- cgit v1.2.3-18-g5258