substrait_explain/parser/
common.rs1use std::{fmt, thread};
2
3use pest::error::{Error as PestError, ErrorVariant};
4use pest::iterators::{Pair, Pairs};
5use pest::{Parser as PestParser, Span};
6use pest_derive::Parser as PestDeriveParser;
7use thiserror::Error;
8
9use crate::extensions::SimpleExtensions;
10use crate::extensions::simple::MissingReference;
11
12#[derive(PestDeriveParser)]
13#[grammar = "parser/expression_grammar.pest"] pub(crate) struct ExpressionParser;
15
16#[derive(Error, Debug, Clone)]
19#[error("{kind} Error parsing {message}:\n{error}")]
20pub struct MessageParseError {
21 message: &'static str,
22 kind: ErrorKind,
23 #[source]
24 error: Box<PestError<Rule>>,
25}
26
27#[derive(Debug, Clone)]
28pub(crate) enum ErrorKind {
29 Syntax,
30 InvalidValue,
31 Lookup(MissingReference),
32}
33
34impl MessageParseError {
35 pub(crate) fn invalid(message: &'static str, span: Span, description: impl ToString) -> Self {
36 let error = PestError::new_from_span(
37 ErrorVariant::CustomError {
38 message: description.to_string(),
39 },
40 span,
41 );
42 Self::new(message, ErrorKind::InvalidValue, Box::new(error))
43 }
44
45 pub(crate) fn lookup(
46 message: &'static str,
47 missing: MissingReference,
48 span: Span,
49 description: impl ToString,
50 ) -> Self {
51 let error = PestError::new_from_span(
52 ErrorVariant::CustomError {
53 message: description.to_string(),
54 },
55 span,
56 );
57 Self::new(message, ErrorKind::Lookup(missing), Box::new(error))
58 }
59}
60
61impl MessageParseError {
62 pub(crate) fn new(message: &'static str, kind: ErrorKind, error: Box<PestError<Rule>>) -> Self {
63 Self {
64 message,
65 kind,
66 error,
67 }
68 }
69}
70
71impl fmt::Display for ErrorKind {
72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73 match self {
74 ErrorKind::Syntax => write!(f, "Syntax"),
75 ErrorKind::InvalidValue => write!(f, "Invalid value"),
76 ErrorKind::Lookup(e) => write!(f, "Invalid reference ({e})"),
77 }
78 }
79}
80
81pub(crate) fn unwrap_single_pair(pair: Pair<Rule>) -> Pair<Rule> {
82 let mut pairs = pair.into_inner();
83 let pair = pairs.next().unwrap();
84 assert_eq!(pairs.next(), None);
85 pair
86}
87
88pub(crate) fn unescape_string(pair: Pair<Rule>) -> String {
101 let s = pair.as_str();
102
103 let (opener, closer) = match pair.as_rule() {
105 Rule::string_literal => ('\'', '\''),
106 Rule::quoted_name => ('"', '"'),
107 _ => panic!(
108 "unescape_string called with unexpected rule: {:?}",
109 pair.as_rule()
110 ),
111 };
112
113 let mut result = String::new();
114 let mut chars = s.chars();
115 let first = chars.next().expect("Empty string literal");
116
117 assert_eq!(
118 first, opener,
119 "Expected opening quote '{opener}', got '{first}'"
120 );
121
122 while let Some(c) = chars.next() {
124 match c {
125 c if c == closer => {
126 assert_eq!(
128 chars.next(),
129 None,
130 "Unexpected characters after closing quote"
131 );
132 break;
133 }
134 '\\' => {
135 let next = chars
136 .next()
137 .expect("Incomplete escape sequence at end of string");
138 match next {
139 'n' => result.push('\n'),
140 't' => result.push('\t'),
141 'r' => result.push('\r'),
142 _ => result.push(next),
145 }
146 }
147 _ => result.push(c),
148 }
149 }
150 result
151}
152
153pub(crate) trait ParsePair: Sized {
157 fn rule() -> Rule;
159
160 fn message() -> &'static str;
162
163 fn parse_pair(pair: Pair<Rule>) -> Self;
167
168 fn parse_str(s: &str) -> Result<Self, MessageParseError> {
169 let mut pairs = <ExpressionParser as PestParser<Rule>>::parse(Self::rule(), s)
170 .map_err(|e| MessageParseError::new(Self::message(), ErrorKind::Syntax, Box::new(e)))?;
171 assert_eq!(pairs.as_str(), s);
172 let pair = pairs.next().unwrap();
173 assert_eq!(pairs.next(), None);
174 Ok(Self::parse_pair(pair))
175 }
176}
177
178pub(crate) trait ScopedParsePair: Sized {
183 fn rule() -> Rule;
185
186 fn message() -> &'static str;
188
189 fn parse_pair(
193 extensions: &SimpleExtensions,
194 pair: Pair<Rule>,
195 ) -> Result<Self, MessageParseError>;
196}
197
198pub(crate) fn iter_pairs(pair: Pairs<'_, Rule>) -> RuleIter<'_> {
199 RuleIter {
200 iter: pair,
201 done: false,
202 }
203}
204
205pub(crate) struct RuleIter<'a> {
206 iter: Pairs<'a, Rule>,
207 done: bool,
209}
210
211impl<'a> From<Pairs<'a, Rule>> for RuleIter<'a> {
212 fn from(iter: Pairs<'a, Rule>) -> Self {
213 RuleIter { iter, done: false }
214 }
215}
216
217impl<'a> RuleIter<'a> {
218 pub(crate) fn peek(&self) -> Option<Pair<'a, Rule>> {
219 self.iter.peek()
220 }
221
222 pub(crate) fn try_pop(&mut self, rule: Rule) -> Option<Pair<'a, Rule>> {
224 match self.peek() {
225 Some(pair) if pair.as_rule() == rule => {
226 self.iter.next();
227 Some(pair)
228 }
229 _ => None,
230 }
231 }
232
233 pub(crate) fn pop(&mut self, rule: Rule) -> Pair<'a, Rule> {
235 let pair = self.iter.next().expect("expected another pair");
236 assert_eq!(
237 pair.as_rule(),
238 rule,
239 "expected rule {:?}, got {:?}",
240 rule,
241 pair.as_rule()
242 );
243 pair
244 }
245
246 pub(crate) fn parse_if_next<T: ParsePair>(&mut self) -> Option<T> {
248 match self.peek() {
249 Some(pair) if pair.as_rule() == T::rule() => {
250 self.iter.next();
251 Some(T::parse_pair(pair))
252 }
253 _ => None,
254 }
255 }
256
257 pub(crate) fn parse_if_next_scoped<T: ScopedParsePair>(
259 &mut self,
260 extensions: &SimpleExtensions,
261 ) -> Option<Result<T, MessageParseError>> {
262 match self.peek() {
263 Some(pair) if pair.as_rule() == T::rule() => {
264 self.iter.next();
265 Some(T::parse_pair(extensions, pair))
266 }
267 _ => None,
268 }
269 }
270
271 pub(crate) fn parse_next<T: ParsePair>(&mut self) -> T {
273 let pair = self.iter.next().unwrap();
274 T::parse_pair(pair)
275 }
276
277 pub(crate) fn parse_next_scoped<T: ScopedParsePair>(
279 &mut self,
280 extensions: &SimpleExtensions,
281 ) -> Result<T, MessageParseError> {
282 let pair = self.iter.next().unwrap();
283 T::parse_pair(extensions, pair)
284 }
285
286 pub(crate) fn done(mut self) {
287 self.done = true;
288 let next = match self.iter.next() {
292 Some(pair) if pair.as_rule() == Rule::EOI => self.iter.next(),
293 other => other,
294 };
295 assert_eq!(next, None);
296 }
297}
298
299impl Drop for RuleIter<'_> {
304 fn drop(&mut self) {
305 if self.done || thread::panicking() {
306 return;
307 }
308 assert_eq!(self.iter.next(), None);
310 }
311}
312
313#[cfg(test)]
314pub(crate) mod test_support {
315 use pest::Parser as PestParser;
316
317 use super::{ErrorKind, ExpressionParser, MessageParseError, ParsePair, ScopedParsePair};
318 use crate::extensions::SimpleExtensions;
319
320 pub(crate) trait Parse {
324 fn parse(input: &str) -> Result<Self, MessageParseError>
325 where
326 Self: Sized;
327 }
328
329 impl<T: ParsePair> Parse for T {
330 fn parse(input: &str) -> Result<Self, MessageParseError> {
331 T::parse_str(input)
332 }
333 }
334
335 pub(crate) trait ScopedParse: Sized {
340 fn parse(extensions: &SimpleExtensions, input: &str) -> Result<Self, MessageParseError>
341 where
342 Self: Sized;
343 }
344
345 impl<T: ScopedParsePair> ScopedParse for T {
346 fn parse(extensions: &SimpleExtensions, input: &str) -> Result<Self, MessageParseError> {
347 let mut pairs = ExpressionParser::parse(Self::rule(), input).map_err(|e| {
348 MessageParseError::new(Self::message(), ErrorKind::Syntax, Box::new(e))
349 })?;
350 assert_eq!(pairs.as_str(), input);
351 let pair = pairs.next().unwrap();
352 assert_eq!(pairs.next(), None);
353 Self::parse_pair(extensions, pair)
354 }
355 }
356}