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
use std::fmt::{
self,
Debug,
Display
};
use crate::grammar::{
NonterminalValue,
TerminalValue,
Symbol
};
#[allow(clippy::module_name_repetitions)]
#[derive(Clone, Copy)]
pub enum ErrorKind<Nt>
where Nt: NonterminalValue
{
NontermExpansionFailed(Nt),
MaxIterationsReached(usize)
}
impl<Nt> Debug for ErrorKind<Nt>
where Nt: NonterminalValue
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::NontermExpansionFailed(_) => write!(
f, "NontermExpansionFailed(_)"
),
Self::MaxIterationsReached(iterations) => write!(
f, "MaxIterationsReached({})", iterations
)
}
}
}
pub struct Error<Nt, T>
where Nt: NonterminalValue,
T: TerminalValue
{
pub state: Vec<Symbol<Nt, T>>,
pub kind: ErrorKind<Nt>
}
impl<Nt, T> Debug for Error<Nt, T>
where Nt: NonterminalValue,
T: TerminalValue
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Error {{ state, kind: {:?} }}", self.kind)
}
}
impl<Nt, T> Display for Error<Nt, T>
where Nt: NonterminalValue,
T: TerminalValue
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.kind {
ErrorKind::NontermExpansionFailed(_) => write!(
f, "no rule to expand nonterminal symbol"
),
ErrorKind::MaxIterationsReached(iterations) => write!(
f,
"reached the maximum {} iterations with {} nonterminal symbols still unexpanded",
iterations,
self.state.iter()
.filter(|symbol| symbol.is_nonterminal())
.count()
)
}
}
}
impl<Nt, T> std::error::Error for Error<Nt, T>
where Nt: NonterminalValue,
T: TerminalValue
{
}
impl<Nt, T> Error<Nt, T>
where Nt: NonterminalValue,
T: TerminalValue
{
pub fn nonterm_expansion_failed(state: Vec<Symbol<Nt, T>>, expanded_nonterm_value: Nt) -> Self {
Self::new(state, ErrorKind::NontermExpansionFailed(expanded_nonterm_value))
}
pub fn max_iterations_reached(state: Vec<Symbol<Nt, T>>, iterations: usize) -> Self {
Self::new(state, ErrorKind::MaxIterationsReached(iterations))
}
fn new(state: Vec<Symbol<Nt, T>>, kind: ErrorKind<Nt>) -> Self {
Self{state, kind}
}
}