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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
use std::path::PathBuf;
use anyhow::anyhow;
use parol_runtime::Location;
use thiserror::Error;
///
/// Error types used by the [crate::parser::ParolGrammar]'s semantic actions
#[derive(Error, Debug)]
pub enum ParolParserError {
/// Undeclared scanner found. Please declare a scanner via %scanner name {{...}}
#[error("{context} - Unknown scanner {name}")]
UnknownScanner {
/// Context (semantic action) where the error was issued
context: String,
/// Name of the unknown scanner state
name: String,
/// Source
input: PathBuf,
/// Location
token: Location,
},
/// Empty Groups () are not allowed.
#[error("{context} - Empty Group not allowed")]
EmptyGroup {
/// Context (semantic action) where the error was issued
context: String,
/// Source
input: PathBuf,
/// Start location
start: Location,
/// End location
end: Location,
},
/// Empty Optionals [] are not allowed.
#[error("{context} - Empty Optionals not allowed")]
EmptyOptional {
/// Context (semantic action) where the error was issued
context: String,
/// Source
input: PathBuf,
/// Start location
start: Location,
/// End location
end: Location,
},
/// Empty Repetitions {{}} are not allowed.
#[error("{context} - Empty Repetitions not allowed")]
EmptyRepetition {
/// Context (semantic action) where the error was issued
context: String,
/// Source
input: PathBuf,
/// Start location
start: Location,
/// End location
end: Location,
},
/// Multiple token aliases that expand to the same text will produce a terminal conflict.
#[error(
r"Multiple token aliases that expand to the same text:
'{first_alias}' and '{second_alias}' expand both to '{expanded}'."
)]
ConflictingTokenAliases {
/// First
first_alias: String,
/// Second
second_alias: String,
/// Expanded
expanded: String,
/// Source
input: PathBuf,
/// First alias
first: Location,
/// Second alias
second: Location,
},
/// Empty Scanner states are not allowed.
#[error("Empty scanner states ({empty_scanners:?}) found")]
EmptyScanners {
/// Names of the empty scanner states
empty_scanners: Vec<String>,
},
/// Unsupported grammar type
#[error("{grammar_type} - Unsupported grammar type")]
UnsupportedGrammarType {
/// The grammar type found
grammar_type: String,
/// Source
input: PathBuf,
/// Location
token: Location,
},
/// Unsupported feature
#[error("{feature} - Unsupported feature")]
UnsupportedFeature {
/// The feature found
feature: String,
/// Hint
hint: String,
/// Source
input: PathBuf,
/// Location
token: Location,
},
/// Invalid token in transition, e.g. a token that is not defined in the grammar
/// is used in a transition. Use a primary non-terminal for the token.
#[error(
"{context} - Invalid token '{token}' in transition. Use a primary non-terminal for the token."
)]
InvalidTokenInTransition {
/// Context where the error was issued
context: String,
/// Token that is not defined matched against a valid primary non-terminal
token: String,
/// Source file
input: PathBuf,
/// Location of the token
location: Location,
},
/// The token that is used to initiate a transition is not defined in this scanner.
#[error("{context} - Token '{token}' is not defined in scanner '{scanner}'")]
TokenIsNotInScanner {
/// Context where the error was issued
context: String,
/// The scanner where the token is not defined
scanner: String,
/// Token that is not defined in the scanner
token: String,
/// Source file
input: PathBuf,
/// Location of the token
location: Location,
},
/// Mixed scanner switching is not allowed - use either parser-based or scanner-based switching.
/// Parser-based switching is done via the %sc, %push and %pop directives productions.
/// Scanner-based switching is done via the %on directive in the header of the grammar file.
///
/// This error can no more occur as of Parol 4, because scanner switching directives
/// have been removed from the grammar syntax.
#[deprecated(
since = "4.0.0",
note = "Scanner switching directives have been removed from the grammar syntax."
)]
#[error("{context} - Mixed scanner switching is not allowed")]
MixedScannerSwitching {
/// Context where the error was issued
context: String,
/// Source file
input: PathBuf,
/// Location of the token
location: Location,
},
}
impl From<ParolParserError> for parol_runtime::ParolError {
fn from(err: ParolParserError) -> Self {
parol_runtime::ParolError::UserError(anyhow!(err))
}
}