summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJSDurand <mmemmew@gmail.com>2023-07-21 16:19:04 +0800
committerJSDurand <mmemmew@gmail.com>2023-07-21 16:19:04 +0800
commit1f010ad1aad8202828ab437ecaf1a635adda3c3f (patch)
tree6767d2190cee27b2eb11bf452b96355936ab6a62
parent31c78b6eb965200ad177aed7b8d31f74559fab8c (diff)
abnf: Correct error reports
Previously the errors emitted while reading abnf grammars reported incorrect indices. Now this is fixed.
-rw-r--r--grammar/src/abnf/mod.rs68
1 files 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<std::io::Error> 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..];