1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use crate::{Parse, RuleResult};
use std::collections::HashSet;
use std::fmt::{self, Debug, Display};
#[derive(PartialEq, Eq, Debug, Clone)]
pub struct ExpectedSet {
expected: HashSet<&'static str>,
}
impl ExpectedSet {
pub fn tokens<'a>(&'a self) -> impl Iterator<Item = &'static str> + 'a {
self.expected.iter().map(|x| *x)
}
}
impl Display for ExpectedSet {
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
if self.expected.is_empty() {
write!(fmt, "<unreported>")?;
} else if self.expected.len() == 1 {
write!(fmt, "{}", self.expected.iter().next().unwrap())?;
} else {
let mut errors = self.tokens().collect::<Vec<_>>();
errors.sort();
let mut iter = errors.into_iter();
write!(fmt, "one of {}", iter.next().unwrap())?;
for elem in iter {
write!(fmt, ", {}", elem)?;
}
}
Ok(())
}
}
#[derive(PartialEq, Eq, Debug, Clone)]
pub struct ParseError<L> {
pub location: L,
pub expected: ExpectedSet,
}
impl<L: Display> Display for ParseError<L> {
fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::result::Result<(), ::std::fmt::Error> {
write!(
fmt,
"error at {}: expected {}",
self.location, self.expected
)
}
}
impl<L: Display + Debug> ::std::error::Error for ParseError<L> {
fn description(&self) -> &str {
"parse error"
}
}
#[doc(hidden)]
pub struct ErrorState {
pub max_err_pos: usize,
pub suppress_fail: usize,
pub reparsing_on_error: bool,
pub expected: ExpectedSet,
}
impl ErrorState {
pub fn new(initial_pos: usize) -> Self {
ErrorState {
max_err_pos: initial_pos,
suppress_fail: 0,
reparsing_on_error: false,
expected: ExpectedSet {
expected: HashSet::new(),
},
}
}
pub fn reparse_for_error(&mut self) {
self.suppress_fail = 0;
self.reparsing_on_error = true;
}
#[inline(never)]
pub fn mark_failure_slow_path(&mut self, pos: usize, expected: &'static str) {
if pos == self.max_err_pos {
self.expected.expected.insert(expected);
}
}
#[inline(always)]
pub fn mark_failure(&mut self, pos: usize, expected: &'static str) -> RuleResult<()> {
if self.suppress_fail == 0 {
if self.reparsing_on_error {
self.mark_failure_slow_path(pos, expected);
} else if pos > self.max_err_pos {
self.max_err_pos = pos;
}
}
RuleResult::Failed
}
pub fn into_parse_error<I: Parse + ?Sized>(self, input: &I) -> ParseError<I::PositionRepr> {
ParseError {
location: Parse::position_repr(input, self.max_err_pos.into()),
expected: self.expected,
}
}
}