parol/parser/errors.rs
1use std::path::PathBuf;
2
3use anyhow::anyhow;
4use parol_runtime::Location;
5use thiserror::Error;
6
7///
8/// Error types used by the [crate::parser::ParolGrammar]'s semantic actions
9#[derive(Error, Debug)]
10pub enum ParolParserError {
11 /// Undeclared scanner found. Please declare a scanner via %scanner name {{...}}
12 #[error("{context} - Unknown scanner {name}")]
13 UnknownScanner {
14 /// Context (semantic action) where the error was issued
15 context: String,
16 /// Name of the unknown scanner state
17 name: String,
18 /// Source
19 input: PathBuf,
20 /// Location
21 token: Location,
22 },
23
24 /// Empty Groups () are not allowed.
25 #[error("{context} - Empty Group not allowed")]
26 EmptyGroup {
27 /// Context (semantic action) where the error was issued
28 context: String,
29 /// Source
30 input: PathBuf,
31 /// Start location
32 start: Location,
33 /// End location
34 end: Location,
35 },
36
37 /// Empty Optionals [] are not allowed.
38 #[error("{context} - Empty Optionals not allowed")]
39 EmptyOptional {
40 /// Context (semantic action) where the error was issued
41 context: String,
42 /// Source
43 input: PathBuf,
44 /// Start location
45 start: Location,
46 /// End location
47 end: Location,
48 },
49
50 /// Empty Repetitions {{}} are not allowed.
51 #[error("{context} - Empty Repetitions not allowed")]
52 EmptyRepetition {
53 /// Context (semantic action) where the error was issued
54 context: String,
55 /// Source
56 input: PathBuf,
57 /// Start location
58 start: Location,
59 /// End location
60 end: Location,
61 },
62
63 /// Multiple token aliases that expand to the same text will produce a terminal conflict.
64 #[error(
65 r"Multiple token aliases that expand to the same text:
66'{first_alias}' and '{second_alias}' expand both to '{expanded}'."
67 )]
68 ConflictingTokenAliases {
69 /// First
70 first_alias: String,
71 /// Second
72 second_alias: String,
73 /// Expanded
74 expanded: String,
75 /// Source
76 input: PathBuf,
77 /// First alias
78 first: Location,
79 /// Second alias
80 second: Location,
81 },
82
83 /// Empty Scanner states are not allowed.
84 #[error("Empty scanner states ({empty_scanners:?}) found")]
85 EmptyScanners {
86 /// Names of the empty scanner states
87 empty_scanners: Vec<String>,
88 },
89
90 /// Unsupported grammar type
91 #[error("{grammar_type} - Unsupported grammar type")]
92 UnsupportedGrammarType {
93 /// The grammar type found
94 grammar_type: String,
95 /// Source
96 input: PathBuf,
97 /// Location
98 token: Location,
99 },
100
101 /// Unsupported feature
102 #[error("{feature} - Unsupported feature")]
103 UnsupportedFeature {
104 /// The feature found
105 feature: String,
106 /// Hint
107 hint: String,
108 /// Source
109 input: PathBuf,
110 /// Location
111 token: Location,
112 },
113
114 /// Invalid token in transition, e.g. a token that is not defined in the grammar
115 /// is used in a transition. Use a primary non-terminal for the token.
116 #[error(
117 "{context} - Invalid token '{token}' in transition. Use a primary non-terminal for the token."
118 )]
119 InvalidTokenInTransition {
120 /// Context where the error was issued
121 context: String,
122 /// Token that is not defined matched against a valid primary non-terminal
123 token: String,
124 /// Source file
125 input: PathBuf,
126 /// Location of the token
127 location: Location,
128 },
129
130 /// The token that is used to initiate a transition is not defined in this scanner.
131 #[error("{context} - Token '{token}' is not defined in scanner '{scanner}'")]
132 TokenIsNotInScanner {
133 /// Context where the error was issued
134 context: String,
135 /// The scanner where the token is not defined
136 scanner: String,
137 /// Token that is not defined in the scanner
138 token: String,
139 /// Source file
140 input: PathBuf,
141 /// Location of the token
142 location: Location,
143 },
144
145 /// Mixed scanner switching is not allowed - use either parser-based or scanner-based switching.
146 /// Parser-based switching is done via the %sc, %push and %pop directives productions.
147 /// Scanner-based switching is done via the %on directive in the header of the grammar file.
148 ///
149 /// This error can no more occur as of Parol 4, because scanner switching directives
150 /// have been removed from the grammar syntax.
151 #[deprecated(
152 since = "4.0.0",
153 note = "Scanner switching directives have been removed from the grammar syntax."
154 )]
155 #[error("{context} - Mixed scanner switching is not allowed")]
156 MixedScannerSwitching {
157 /// Context where the error was issued
158 context: String,
159 /// Source file
160 input: PathBuf,
161 /// Location of the token
162 location: Location,
163 },
164}
165
166impl From<ParolParserError> for parol_runtime::ParolError {
167 fn from(err: ParolParserError) -> Self {
168 parol_runtime::ParolError::UserError(anyhow!(err))
169 }
170}