• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // pest. The Elegant Parser
2 // Copyright (c) 2018 Dragoș Tiselice
3 //
4 // Licensed under the Apache License, Version 2.0
5 // <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
6 // license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7 // option. All files in the project carrying such notice may not be copied,
8 // modified, or distributed except according to those terms.
9 
10 //! Types and helpers for the pest's own grammar parser.
11 
12 use std::char;
13 use std::iter::Peekable;
14 
15 use pest::error::{Error, ErrorVariant};
16 use pest::iterators::{Pair, Pairs};
17 use pest::pratt_parser::{Assoc, Op, PrattParser};
18 use pest::{Parser, Span};
19 
20 use crate::ast::{Expr, Rule as AstRule, RuleType};
21 use crate::validator;
22 
23 /// TODO: fix the generator to at least add explicit lifetimes
24 #[allow(
25     missing_docs,
26     unused_attributes,
27     elided_lifetimes_in_paths,
28     unused_qualifications
29 )]
30 mod grammar {
31     include!("grammar.rs");
32 }
33 
34 pub use self::grammar::*;
35 
36 /// A helper that will parse using the pest grammar
37 #[allow(clippy::perf)]
parse(rule: Rule, data: &str) -> Result<Pairs<'_, Rule>, Error<Rule>>38 pub fn parse(rule: Rule, data: &str) -> Result<Pairs<'_, Rule>, Error<Rule>> {
39     PestParser::parse(rule, data)
40 }
41 
42 /// The pest grammar rule
43 #[derive(Clone, Debug, Eq, PartialEq)]
44 pub struct ParserRule<'i> {
45     /// The rule's name
46     pub name: String,
47     /// The rule's span
48     pub span: Span<'i>,
49     /// The rule's type
50     pub ty: RuleType,
51     /// The rule's parser node
52     pub node: ParserNode<'i>,
53 }
54 
55 /// The pest grammar node
56 #[derive(Clone, Debug, Eq, PartialEq)]
57 pub struct ParserNode<'i> {
58     /// The node's expression
59     pub expr: ParserExpr<'i>,
60     /// The node's span
61     pub span: Span<'i>,
62 }
63 
64 impl<'i> ParserNode<'i> {
65     /// will remove nodes that do not match `f`
filter_map_top_down<F, T>(self, mut f: F) -> Vec<T> where F: FnMut(ParserNode<'i>) -> Option<T>,66     pub fn filter_map_top_down<F, T>(self, mut f: F) -> Vec<T>
67     where
68         F: FnMut(ParserNode<'i>) -> Option<T>,
69     {
70         pub fn filter_internal<'i, F, T>(node: ParserNode<'i>, f: &mut F, result: &mut Vec<T>)
71         where
72             F: FnMut(ParserNode<'i>) -> Option<T>,
73         {
74             if let Some(value) = f(node.clone()) {
75                 result.push(value);
76             }
77 
78             match node.expr {
79                 // TODO: Use box syntax when it gets stabilized.
80                 ParserExpr::PosPred(node) => {
81                     filter_internal(*node, f, result);
82                 }
83                 ParserExpr::NegPred(node) => {
84                     filter_internal(*node, f, result);
85                 }
86                 ParserExpr::Seq(lhs, rhs) => {
87                     filter_internal(*lhs, f, result);
88                     filter_internal(*rhs, f, result);
89                 }
90                 ParserExpr::Choice(lhs, rhs) => {
91                     filter_internal(*lhs, f, result);
92                     filter_internal(*rhs, f, result);
93                 }
94                 ParserExpr::Rep(node) => {
95                     filter_internal(*node, f, result);
96                 }
97                 ParserExpr::RepOnce(node) => {
98                     filter_internal(*node, f, result);
99                 }
100                 ParserExpr::RepExact(node, _) => {
101                     filter_internal(*node, f, result);
102                 }
103                 ParserExpr::RepMin(node, _) => {
104                     filter_internal(*node, f, result);
105                 }
106                 ParserExpr::RepMax(node, _) => {
107                     filter_internal(*node, f, result);
108                 }
109                 ParserExpr::RepMinMax(node, ..) => {
110                     filter_internal(*node, f, result);
111                 }
112                 ParserExpr::Opt(node) => {
113                     filter_internal(*node, f, result);
114                 }
115                 ParserExpr::Push(node) => {
116                     filter_internal(*node, f, result);
117                 }
118                 _ => (),
119             }
120         }
121 
122         let mut result = vec![];
123 
124         filter_internal(self, &mut f, &mut result);
125 
126         result
127     }
128 }
129 
130 /// All possible parser expressions
131 #[derive(Clone, Debug, Eq, PartialEq)]
132 pub enum ParserExpr<'i> {
133     /// Matches an exact string, e.g. `"a"`
134     Str(String),
135     /// Matches an exact string, case insensitively (ASCII only), e.g. `^"a"`
136     Insens(String),
137     /// Matches one character in the range, e.g. `'a'..'z'`
138     Range(String, String),
139     /// Matches the rule with the given name, e.g. `a`
140     Ident(String),
141     /// Matches a custom part of the stack, e.g. `PEEK[..]`
142     PeekSlice(i32, Option<i32>),
143     /// Positive lookahead; matches expression without making progress, e.g. `&e`
144     PosPred(Box<ParserNode<'i>>),
145     /// Negative lookahead; matches if expression doesn't match, without making progress, e.g. `!e`
146     NegPred(Box<ParserNode<'i>>),
147     /// Matches a sequence of two expressions, e.g. `e1 ~ e2`
148     Seq(Box<ParserNode<'i>>, Box<ParserNode<'i>>),
149     /// Matches either of two expressions, e.g. `e1 | e2`
150     Choice(Box<ParserNode<'i>>, Box<ParserNode<'i>>),
151     /// Optionally matches an expression, e.g. `e?`
152     Opt(Box<ParserNode<'i>>),
153     /// Matches an expression zero or more times, e.g. `e*`
154     Rep(Box<ParserNode<'i>>),
155     /// Matches an expression one or more times, e.g. `e+`
156     RepOnce(Box<ParserNode<'i>>),
157     /// Matches an expression an exact number of times, e.g. `e{n}`
158     RepExact(Box<ParserNode<'i>>, u32),
159     /// Matches an expression at least a number of times, e.g. `e{n,}`
160     RepMin(Box<ParserNode<'i>>, u32),
161     /// Matches an expression at most a number of times, e.g. `e{,n}`
162     RepMax(Box<ParserNode<'i>>, u32),
163     /// Matches an expression a number of times within a range, e.g. `e{m, n}`
164     RepMinMax(Box<ParserNode<'i>>, u32, u32),
165     /// Matches an expression and pushes it to the stack, e.g. `push(e)`
166     Push(Box<ParserNode<'i>>),
167 }
168 
convert_rule(rule: ParserRule<'_>) -> AstRule169 fn convert_rule(rule: ParserRule<'_>) -> AstRule {
170     let ParserRule { name, ty, node, .. } = rule;
171     let expr = convert_node(node);
172     AstRule { name, ty, expr }
173 }
174 
convert_node(node: ParserNode<'_>) -> Expr175 fn convert_node(node: ParserNode<'_>) -> Expr {
176     match node.expr {
177         ParserExpr::Str(string) => Expr::Str(string),
178         ParserExpr::Insens(string) => Expr::Insens(string),
179         ParserExpr::Range(start, end) => Expr::Range(start, end),
180         ParserExpr::Ident(ident) => Expr::Ident(ident),
181         ParserExpr::PeekSlice(start, end) => Expr::PeekSlice(start, end),
182         ParserExpr::PosPred(node) => Expr::PosPred(Box::new(convert_node(*node))),
183         ParserExpr::NegPred(node) => Expr::NegPred(Box::new(convert_node(*node))),
184         ParserExpr::Seq(node1, node2) => Expr::Seq(
185             Box::new(convert_node(*node1)),
186             Box::new(convert_node(*node2)),
187         ),
188         ParserExpr::Choice(node1, node2) => Expr::Choice(
189             Box::new(convert_node(*node1)),
190             Box::new(convert_node(*node2)),
191         ),
192         ParserExpr::Opt(node) => Expr::Opt(Box::new(convert_node(*node))),
193         ParserExpr::Rep(node) => Expr::Rep(Box::new(convert_node(*node))),
194         ParserExpr::RepOnce(node) => Expr::RepOnce(Box::new(convert_node(*node))),
195         ParserExpr::RepExact(node, num) => Expr::RepExact(Box::new(convert_node(*node)), num),
196         ParserExpr::RepMin(node, max) => Expr::RepMin(Box::new(convert_node(*node)), max),
197         ParserExpr::RepMax(node, max) => Expr::RepMax(Box::new(convert_node(*node)), max),
198         ParserExpr::RepMinMax(node, min, max) => {
199             Expr::RepMinMax(Box::new(convert_node(*node)), min, max)
200         }
201         ParserExpr::Push(node) => Expr::Push(Box::new(convert_node(*node))),
202     }
203 }
204 
205 /// Converts a parser's result (`Pairs`) to an AST
consume_rules(pairs: Pairs<'_, Rule>) -> Result<Vec<AstRule>, Vec<Error<Rule>>>206 pub fn consume_rules(pairs: Pairs<'_, Rule>) -> Result<Vec<AstRule>, Vec<Error<Rule>>> {
207     let rules = consume_rules_with_spans(pairs)?;
208     let errors = validator::validate_ast(&rules);
209     if errors.is_empty() {
210         Ok(rules.into_iter().map(convert_rule).collect())
211     } else {
212         Err(errors)
213     }
214 }
215 
216 /// A helper function to rename verbose rules
217 /// for the sake of better error messages
218 #[inline]
rename_meta_rule(rule: &Rule) -> String219 pub fn rename_meta_rule(rule: &Rule) -> String {
220     match *rule {
221         Rule::grammar_rule => "rule".to_owned(),
222         Rule::_push => "PUSH".to_owned(),
223         Rule::assignment_operator => "`=`".to_owned(),
224         Rule::silent_modifier => "`_`".to_owned(),
225         Rule::atomic_modifier => "`@`".to_owned(),
226         Rule::compound_atomic_modifier => "`$`".to_owned(),
227         Rule::non_atomic_modifier => "`!`".to_owned(),
228         Rule::opening_brace => "`{`".to_owned(),
229         Rule::closing_brace => "`}`".to_owned(),
230         Rule::opening_brack => "`[`".to_owned(),
231         Rule::closing_brack => "`]`".to_owned(),
232         Rule::opening_paren => "`(`".to_owned(),
233         Rule::positive_predicate_operator => "`&`".to_owned(),
234         Rule::negative_predicate_operator => "`!`".to_owned(),
235         Rule::sequence_operator => "`&`".to_owned(),
236         Rule::choice_operator => "`|`".to_owned(),
237         Rule::optional_operator => "`?`".to_owned(),
238         Rule::repeat_operator => "`*`".to_owned(),
239         Rule::repeat_once_operator => "`+`".to_owned(),
240         Rule::comma => "`,`".to_owned(),
241         Rule::closing_paren => "`)`".to_owned(),
242         Rule::quote => "`\"`".to_owned(),
243         Rule::insensitive_string => "`^`".to_owned(),
244         Rule::range_operator => "`..`".to_owned(),
245         Rule::single_quote => "`'`".to_owned(),
246         Rule::grammar_doc => "//!".to_owned(),
247         Rule::line_doc => "///".to_owned(),
248         other_rule => format!("{:?}", other_rule),
249     }
250 }
251 
consume_rules_with_spans( pairs: Pairs<'_, Rule>, ) -> Result<Vec<ParserRule<'_>>, Vec<Error<Rule>>>252 fn consume_rules_with_spans(
253     pairs: Pairs<'_, Rule>,
254 ) -> Result<Vec<ParserRule<'_>>, Vec<Error<Rule>>> {
255     let pratt = PrattParser::new()
256         .op(Op::infix(Rule::choice_operator, Assoc::Left))
257         .op(Op::infix(Rule::sequence_operator, Assoc::Left));
258 
259     pairs
260         .filter(|pair| pair.as_rule() == Rule::grammar_rule)
261         .filter(|pair| {
262             // To ignore `grammar_rule > line_doc` pairs
263             let mut pairs = pair.clone().into_inner();
264             let pair = pairs.next().unwrap();
265 
266             pair.as_rule() != Rule::line_doc
267         })
268         .map(|pair| {
269             let mut pairs = pair.into_inner().peekable();
270 
271             let span = pairs.next().unwrap().as_span();
272             let name = span.as_str().to_owned();
273 
274             pairs.next().unwrap(); // assignment_operator
275 
276             let ty = if pairs.peek().unwrap().as_rule() != Rule::opening_brace {
277                 match pairs.next().unwrap().as_rule() {
278                     Rule::silent_modifier => RuleType::Silent,
279                     Rule::atomic_modifier => RuleType::Atomic,
280                     Rule::compound_atomic_modifier => RuleType::CompoundAtomic,
281                     Rule::non_atomic_modifier => RuleType::NonAtomic,
282                     _ => unreachable!(),
283                 }
284             } else {
285                 RuleType::Normal
286             };
287 
288             pairs.next().unwrap(); // opening_brace
289 
290             // skip initial infix operators
291             let mut inner_nodes = pairs.next().unwrap().into_inner().peekable();
292             if inner_nodes.peek().unwrap().as_rule() == Rule::choice_operator {
293                 inner_nodes.next().unwrap();
294             }
295 
296             let node = consume_expr(inner_nodes, &pratt)?;
297 
298             Ok(ParserRule {
299                 name,
300                 span,
301                 ty,
302                 node,
303             })
304         })
305         .collect()
306 }
307 
consume_expr<'i>( pairs: Peekable<Pairs<'i, Rule>>, pratt: &PrattParser<Rule>, ) -> Result<ParserNode<'i>, Vec<Error<Rule>>>308 fn consume_expr<'i>(
309     pairs: Peekable<Pairs<'i, Rule>>,
310     pratt: &PrattParser<Rule>,
311 ) -> Result<ParserNode<'i>, Vec<Error<Rule>>> {
312     fn unaries<'i>(
313         mut pairs: Peekable<Pairs<'i, Rule>>,
314         pratt: &PrattParser<Rule>,
315     ) -> Result<ParserNode<'i>, Vec<Error<Rule>>> {
316         let pair = pairs.next().unwrap();
317 
318         let node = match pair.as_rule() {
319             Rule::opening_paren => {
320                 let node = unaries(pairs, pratt)?;
321                 let end = node.span.end_pos();
322 
323                 ParserNode {
324                     expr: node.expr,
325                     span: pair.as_span().start_pos().span(&end),
326                 }
327             }
328             Rule::positive_predicate_operator => {
329                 let node = unaries(pairs, pratt)?;
330                 let end = node.span.end_pos();
331 
332                 ParserNode {
333                     expr: ParserExpr::PosPred(Box::new(node)),
334                     span: pair.as_span().start_pos().span(&end),
335                 }
336             }
337             Rule::negative_predicate_operator => {
338                 let node = unaries(pairs, pratt)?;
339                 let end = node.span.end_pos();
340 
341                 ParserNode {
342                     expr: ParserExpr::NegPred(Box::new(node)),
343                     span: pair.as_span().start_pos().span(&end),
344                 }
345             }
346             other_rule => {
347                 let node = match other_rule {
348                     Rule::expression => consume_expr(pair.into_inner().peekable(), pratt)?,
349                     Rule::_push => {
350                         let start = pair.clone().as_span().start_pos();
351                         let mut pairs = pair.into_inner();
352                         pairs.next().unwrap(); // opening_paren
353                         let pair = pairs.next().unwrap();
354 
355                         let node = consume_expr(pair.into_inner().peekable(), pratt)?;
356                         let end = node.span.end_pos();
357 
358                         ParserNode {
359                             expr: ParserExpr::Push(Box::new(node)),
360                             span: start.span(&end),
361                         }
362                     }
363                     Rule::peek_slice => {
364                         let mut pairs = pair.clone().into_inner();
365                         pairs.next().unwrap(); // opening_brack
366                         let pair_start = pairs.next().unwrap(); // .. or integer
367                         let start: i32 = match pair_start.as_rule() {
368                             Rule::range_operator => 0,
369                             Rule::integer => {
370                                 pairs.next().unwrap(); // ..
371                                 pair_start.as_str().parse().unwrap()
372                             }
373                             _ => unreachable!(),
374                         };
375                         let pair_end = pairs.next().unwrap(); // integer or }
376                         let end: Option<i32> = match pair_end.as_rule() {
377                             Rule::closing_brack => None,
378                             Rule::integer => {
379                                 pairs.next().unwrap(); // }
380                                 Some(pair_end.as_str().parse().unwrap())
381                             }
382                             _ => unreachable!(),
383                         };
384                         ParserNode {
385                             expr: ParserExpr::PeekSlice(start, end),
386                             span: pair.as_span(),
387                         }
388                     }
389                     Rule::identifier => ParserNode {
390                         expr: ParserExpr::Ident(pair.as_str().to_owned()),
391                         span: pair.clone().as_span(),
392                     },
393                     Rule::string => {
394                         let string = unescape(pair.as_str()).expect("incorrect string literal");
395                         ParserNode {
396                             expr: ParserExpr::Str(string[1..string.len() - 1].to_owned()),
397                             span: pair.clone().as_span(),
398                         }
399                     }
400                     Rule::insensitive_string => {
401                         let string = unescape(pair.as_str()).expect("incorrect string literal");
402                         ParserNode {
403                             expr: ParserExpr::Insens(string[2..string.len() - 1].to_owned()),
404                             span: pair.clone().as_span(),
405                         }
406                     }
407                     Rule::range => {
408                         let mut pairs = pair.into_inner();
409                         let pair = pairs.next().unwrap();
410                         let start = unescape(pair.as_str()).expect("incorrect char literal");
411                         let start_pos = pair.clone().as_span().start_pos();
412                         pairs.next();
413                         let pair = pairs.next().unwrap();
414                         let end = unescape(pair.as_str()).expect("incorrect char literal");
415                         let end_pos = pair.clone().as_span().end_pos();
416 
417                         ParserNode {
418                             expr: ParserExpr::Range(
419                                 start[1..start.len() - 1].to_owned(),
420                                 end[1..end.len() - 1].to_owned(),
421                             ),
422                             span: start_pos.span(&end_pos),
423                         }
424                     }
425                     _ => unreachable!(),
426                 };
427 
428                 pairs.fold(
429                     Ok(node),
430                     |node: Result<ParserNode<'i>, Vec<Error<Rule>>>, pair| {
431                         let node = node?;
432 
433                         let node = match pair.as_rule() {
434                             Rule::optional_operator => {
435                                 let start = node.span.start_pos();
436                                 ParserNode {
437                                     expr: ParserExpr::Opt(Box::new(node)),
438                                     span: start.span(&pair.as_span().end_pos()),
439                                 }
440                             }
441                             Rule::repeat_operator => {
442                                 let start = node.span.start_pos();
443                                 ParserNode {
444                                     expr: ParserExpr::Rep(Box::new(node)),
445                                     span: start.span(&pair.as_span().end_pos()),
446                                 }
447                             }
448                             Rule::repeat_once_operator => {
449                                 let start = node.span.start_pos();
450                                 ParserNode {
451                                     expr: ParserExpr::RepOnce(Box::new(node)),
452                                     span: start.span(&pair.as_span().end_pos()),
453                                 }
454                             }
455                             Rule::repeat_exact => {
456                                 let mut inner = pair.clone().into_inner();
457 
458                                 inner.next().unwrap(); // opening_brace
459 
460                                 let number = inner.next().unwrap();
461                                 let num = if let Ok(num) = number.as_str().parse::<u32>() {
462                                     num
463                                 } else {
464                                     return Err(vec![Error::new_from_span(
465                                         ErrorVariant::CustomError {
466                                             message: "number cannot overflow u32".to_owned(),
467                                         },
468                                         number.as_span(),
469                                     )]);
470                                 };
471 
472                                 if num == 0 {
473                                     let error: Error<Rule> = Error::new_from_span(
474                                         ErrorVariant::CustomError {
475                                             message: "cannot repeat 0 times".to_owned(),
476                                         },
477                                         number.as_span(),
478                                     );
479 
480                                     return Err(vec![error]);
481                                 }
482 
483                                 let start = node.span.start_pos();
484                                 ParserNode {
485                                     expr: ParserExpr::RepExact(Box::new(node), num),
486                                     span: start.span(&pair.as_span().end_pos()),
487                                 }
488                             }
489                             Rule::repeat_min => {
490                                 let mut inner = pair.clone().into_inner();
491 
492                                 inner.next().unwrap(); // opening_brace
493 
494                                 let min_number = inner.next().unwrap();
495                                 let min = if let Ok(min) = min_number.as_str().parse::<u32>() {
496                                     min
497                                 } else {
498                                     return Err(vec![Error::new_from_span(
499                                         ErrorVariant::CustomError {
500                                             message: "number cannot overflow u32".to_owned(),
501                                         },
502                                         min_number.as_span(),
503                                     )]);
504                                 };
505 
506                                 let start = node.span.start_pos();
507                                 ParserNode {
508                                     expr: ParserExpr::RepMin(Box::new(node), min),
509                                     span: start.span(&pair.as_span().end_pos()),
510                                 }
511                             }
512                             Rule::repeat_max => {
513                                 let mut inner = pair.clone().into_inner();
514 
515                                 inner.next().unwrap(); // opening_brace
516                                 inner.next().unwrap(); // comma
517 
518                                 let max_number = inner.next().unwrap();
519                                 let max = if let Ok(max) = max_number.as_str().parse::<u32>() {
520                                     max
521                                 } else {
522                                     return Err(vec![Error::new_from_span(
523                                         ErrorVariant::CustomError {
524                                             message: "number cannot overflow u32".to_owned(),
525                                         },
526                                         max_number.as_span(),
527                                     )]);
528                                 };
529 
530                                 if max == 0 {
531                                     let error: Error<Rule> = Error::new_from_span(
532                                         ErrorVariant::CustomError {
533                                             message: "cannot repeat 0 times".to_owned(),
534                                         },
535                                         max_number.as_span(),
536                                     );
537 
538                                     return Err(vec![error]);
539                                 }
540 
541                                 let start = node.span.start_pos();
542                                 ParserNode {
543                                     expr: ParserExpr::RepMax(Box::new(node), max),
544                                     span: start.span(&pair.as_span().end_pos()),
545                                 }
546                             }
547                             Rule::repeat_min_max => {
548                                 let mut inner = pair.clone().into_inner();
549 
550                                 inner.next().unwrap(); // opening_brace
551 
552                                 let min_number = inner.next().unwrap();
553                                 let min = if let Ok(min) = min_number.as_str().parse::<u32>() {
554                                     min
555                                 } else {
556                                     return Err(vec![Error::new_from_span(
557                                         ErrorVariant::CustomError {
558                                             message: "number cannot overflow u32".to_owned(),
559                                         },
560                                         min_number.as_span(),
561                                     )]);
562                                 };
563 
564                                 inner.next().unwrap(); // comma
565 
566                                 let max_number = inner.next().unwrap();
567                                 let max = if let Ok(max) = max_number.as_str().parse::<u32>() {
568                                     max
569                                 } else {
570                                     return Err(vec![Error::new_from_span(
571                                         ErrorVariant::CustomError {
572                                             message: "number cannot overflow u32".to_owned(),
573                                         },
574                                         max_number.as_span(),
575                                     )]);
576                                 };
577 
578                                 if max == 0 {
579                                     let error: Error<Rule> = Error::new_from_span(
580                                         ErrorVariant::CustomError {
581                                             message: "cannot repeat 0 times".to_owned(),
582                                         },
583                                         max_number.as_span(),
584                                     );
585 
586                                     return Err(vec![error]);
587                                 }
588 
589                                 let start = node.span.start_pos();
590                                 ParserNode {
591                                     expr: ParserExpr::RepMinMax(Box::new(node), min, max),
592                                     span: start.span(&pair.as_span().end_pos()),
593                                 }
594                             }
595                             Rule::closing_paren => {
596                                 let start = node.span.start_pos();
597 
598                                 ParserNode {
599                                     expr: node.expr,
600                                     span: start.span(&pair.as_span().end_pos()),
601                                 }
602                             }
603                             _ => unreachable!(),
604                         };
605 
606                         Ok(node)
607                     },
608                 )?
609             }
610         };
611 
612         Ok(node)
613     }
614 
615     let term = |pair: Pair<'i, Rule>| unaries(pair.into_inner().peekable(), pratt);
616     let infix = |lhs: Result<ParserNode<'i>, Vec<Error<Rule>>>,
617                  op: Pair<'i, Rule>,
618                  rhs: Result<ParserNode<'i>, Vec<Error<Rule>>>| match op.as_rule() {
619         Rule::sequence_operator => {
620             let lhs = lhs?;
621             let rhs = rhs?;
622 
623             let start = lhs.span.start_pos();
624             let end = rhs.span.end_pos();
625 
626             Ok(ParserNode {
627                 expr: ParserExpr::Seq(Box::new(lhs), Box::new(rhs)),
628                 span: start.span(&end),
629             })
630         }
631         Rule::choice_operator => {
632             let lhs = lhs?;
633             let rhs = rhs?;
634 
635             let start = lhs.span.start_pos();
636             let end = rhs.span.end_pos();
637 
638             Ok(ParserNode {
639                 expr: ParserExpr::Choice(Box::new(lhs), Box::new(rhs)),
640                 span: start.span(&end),
641             })
642         }
643         _ => unreachable!(),
644     };
645 
646     pratt.map_primary(term).map_infix(infix).parse(pairs)
647 }
648 
unescape(string: &str) -> Option<String>649 fn unescape(string: &str) -> Option<String> {
650     let mut result = String::new();
651     let mut chars = string.chars();
652 
653     loop {
654         match chars.next() {
655             Some('\\') => match chars.next()? {
656                 '"' => result.push('"'),
657                 '\\' => result.push('\\'),
658                 'r' => result.push('\r'),
659                 'n' => result.push('\n'),
660                 't' => result.push('\t'),
661                 '0' => result.push('\0'),
662                 '\'' => result.push('\''),
663                 'x' => {
664                     let string: String = chars.clone().take(2).collect();
665 
666                     if string.len() != 2 {
667                         return None;
668                     }
669 
670                     for _ in 0..string.len() {
671                         chars.next()?;
672                     }
673 
674                     let value = u8::from_str_radix(&string, 16).ok()?;
675 
676                     result.push(char::from(value));
677                 }
678                 'u' => {
679                     if chars.next()? != '{' {
680                         return None;
681                     }
682 
683                     let string: String = chars.clone().take_while(|c| *c != '}').collect();
684 
685                     if string.len() < 2 || 6 < string.len() {
686                         return None;
687                     }
688 
689                     for _ in 0..string.len() + 1 {
690                         chars.next()?;
691                     }
692 
693                     let value = u32::from_str_radix(&string, 16).ok()?;
694 
695                     result.push(char::from_u32(value)?);
696                 }
697                 _ => return None,
698             },
699             Some(c) => result.push(c),
700             None => return Some(result),
701         };
702     }
703 }
704 
705 #[cfg(test)]
706 mod tests {
707     use std::convert::TryInto;
708 
709     use super::super::unwrap_or_report;
710     use super::*;
711 
712     #[test]
rules()713     fn rules() {
714         parses_to! {
715             parser: PestParser,
716             input: "a = { b } c = { d }",
717             rule: Rule::grammar_rules,
718             tokens: [
719                 grammar_rule(0, 9, [
720                     identifier(0, 1),
721                     assignment_operator(2, 3),
722                     opening_brace(4, 5),
723                     expression(6, 8, [
724                         term(6, 8, [
725                             identifier(6, 7)
726                         ])
727                     ]),
728                     closing_brace(8, 9)
729                 ]),
730                 grammar_rule(10, 19, [
731                     identifier(10, 11),
732                     assignment_operator(12, 13),
733                     opening_brace(14, 15),
734                     expression(16, 18, [
735                         term(16, 18, [
736                             identifier(16, 17)
737                         ])
738                     ]),
739                     closing_brace(18, 19)
740                 ])
741             ]
742         };
743     }
744 
745     #[test]
rule()746     fn rule() {
747         parses_to! {
748             parser: PestParser,
749             input: "a = ! { b ~ c }",
750             rule: Rule::grammar_rule,
751             tokens: [
752                 grammar_rule(0, 15, [
753                     identifier(0, 1),
754                     assignment_operator(2, 3),
755                     non_atomic_modifier(4, 5),
756                     opening_brace(6, 7),
757                     expression(8, 14, [
758                         term(8, 10, [
759                             identifier(8, 9)
760                         ]),
761                         sequence_operator(10, 11),
762                         term(12, 14, [
763                             identifier(12, 13)
764                         ])
765                     ]),
766                     closing_brace(14, 15)
767                 ])
768             ]
769         };
770     }
771 
772     #[test]
expression()773     fn expression() {
774         parses_to! {
775             parser: PestParser,
776             input: "_a | 'a'..'b' ~ !^\"abc\" ~ (d | e)*?",
777             rule: Rule::expression,
778             tokens: [
779                 expression(0, 35, [
780                     term(0, 3, [
781                         identifier(0, 2)
782                     ]),
783                     choice_operator(3, 4),
784                     term(5, 14, [
785                         range(5, 13, [
786                             character(5, 8, [
787                                 single_quote(5, 6),
788                                 inner_chr(6, 7),
789                                 single_quote(7, 8)
790                             ]),
791                             range_operator(8, 10),
792                             character(10, 13, [
793                                 single_quote(10, 11),
794                                 inner_chr(11, 12),
795                                 single_quote(12, 13)
796                             ])
797                         ])
798                     ]),
799                     sequence_operator(14, 15),
800                     term(16, 24, [
801                         negative_predicate_operator(16, 17),
802                         insensitive_string(17, 23, [
803                             string(18, 23, [
804                                 quote(18, 19),
805                                 inner_str(19, 22),
806                                 quote(22, 23)
807                             ])
808                         ])
809                     ]),
810                     sequence_operator(24, 25),
811                     term(26, 35, [
812                         opening_paren(26, 27),
813                         expression(27, 32, [
814                             term(27, 29, [
815                                 identifier(27, 28)
816                             ]),
817                             choice_operator(29, 30),
818                             term(31, 32, [
819                                 identifier(31, 32)
820                             ])
821                         ]),
822                         closing_paren(32, 33),
823                         repeat_operator(33, 34),
824                         optional_operator(34, 35)
825                     ])
826                 ])
827             ]
828         };
829     }
830 
831     #[test]
repeat_exact()832     fn repeat_exact() {
833         parses_to! {
834             parser: PestParser,
835             input: "{1}",
836             rule: Rule::repeat_exact,
837             tokens: [
838                 repeat_exact(0, 3, [
839                     opening_brace(0, 1),
840                     number(1, 2),
841                     closing_brace(2, 3)
842                 ])
843             ]
844         };
845     }
846 
847     #[test]
repeat_min()848     fn repeat_min() {
849         parses_to! {
850             parser: PestParser,
851             input: "{2,}",
852             rule: Rule::repeat_min,
853             tokens: [
854                 repeat_min(0, 4, [
855                     opening_brace(0,1),
856                     number(1,2),
857                     comma(2,3),
858                     closing_brace(3,4)
859                 ])
860             ]
861         }
862     }
863 
864     #[test]
repeat_max()865     fn repeat_max() {
866         parses_to! {
867             parser: PestParser,
868             input: "{, 3}",
869             rule: Rule::repeat_max,
870             tokens: [
871                 repeat_max(0, 5, [
872                     opening_brace(0,1),
873                     comma(1,2),
874                     number(3,4),
875                     closing_brace(4,5)
876                 ])
877             ]
878         }
879     }
880 
881     #[test]
repeat_min_max()882     fn repeat_min_max() {
883         parses_to! {
884             parser: PestParser,
885             input: "{1, 2}",
886             rule: Rule::repeat_min_max,
887             tokens: [
888                 repeat_min_max(0, 6, [
889                     opening_brace(0, 1),
890                     number(1, 2),
891                     comma(2, 3),
892                     number(4, 5),
893                     closing_brace(5, 6)
894                 ])
895             ]
896         };
897     }
898 
899     #[test]
push()900     fn push() {
901         parses_to! {
902             parser: PestParser,
903             input: "PUSH ( a )",
904             rule: Rule::_push,
905             tokens: [
906                 _push(0, 10, [
907                     opening_paren(5, 6),
908                     expression(7, 9, [
909                         term(7, 9, [
910                             identifier(7, 8)
911                         ])
912                     ]),
913                     closing_paren(9, 10)
914                 ])
915             ]
916         };
917     }
918 
919     #[test]
peek_slice_all()920     fn peek_slice_all() {
921         parses_to! {
922             parser: PestParser,
923             input: "PEEK[..]",
924             rule: Rule::peek_slice,
925             tokens: [
926                 peek_slice(0, 8, [
927                     opening_brack(4, 5),
928                     range_operator(5, 7),
929                     closing_brack(7, 8)
930                 ])
931             ]
932         };
933     }
934 
935     #[test]
peek_slice_start()936     fn peek_slice_start() {
937         parses_to! {
938             parser: PestParser,
939             input: "PEEK[1..]",
940             rule: Rule::peek_slice,
941             tokens: [
942                 peek_slice(0, 9, [
943                     opening_brack(4, 5),
944                     integer(5, 6),
945                     range_operator(6, 8),
946                     closing_brack(8, 9)
947                 ])
948             ]
949         };
950     }
951 
952     #[test]
peek_slice_end()953     fn peek_slice_end() {
954         parses_to! {
955             parser: PestParser,
956             input: "PEEK[ ..-1]",
957             rule: Rule::peek_slice,
958             tokens: [
959                 peek_slice(0, 11, [
960                     opening_brack(4, 5),
961                     range_operator(6, 8),
962                     integer(8, 10),
963                     closing_brack(10, 11)
964                 ])
965             ]
966         };
967     }
968 
969     #[test]
peek_slice_start_end()970     fn peek_slice_start_end() {
971         parses_to! {
972             parser: PestParser,
973             input: "PEEK[-5..10]",
974             rule: Rule::peek_slice,
975             tokens: [
976                 peek_slice(0, 12, [
977                     opening_brack(4, 5),
978                     integer(5, 7),
979                     range_operator(7, 9),
980                     integer(9, 11),
981                     closing_brack(11, 12)
982                 ])
983             ]
984         };
985     }
986 
987     #[test]
identifier()988     fn identifier() {
989         parses_to! {
990             parser: PestParser,
991             input: "_a8943",
992             rule: Rule::identifier,
993             tokens: [
994                 identifier(0, 6)
995             ]
996         };
997     }
998 
999     #[test]
string()1000     fn string() {
1001         parses_to! {
1002             parser: PestParser,
1003             input: "\"aaaaa\\n\\r\\t\\\\\\0\\'\\\"\\x0F\\u{123abC}\\u{12}aaaaa\"",
1004             rule: Rule::string,
1005             tokens: [
1006                 string(0, 46, [
1007                     quote(0, 1),
1008                     inner_str(1, 45),
1009                     quote(45, 46)
1010                 ])
1011             ]
1012         };
1013     }
1014 
1015     #[test]
insensitive_string()1016     fn insensitive_string() {
1017         parses_to! {
1018             parser: PestParser,
1019             input: "^  \"\\\"hi\"",
1020             rule: Rule::insensitive_string,
1021             tokens: [
1022                 insensitive_string(0, 9, [
1023                     string(3, 9, [
1024                         quote(3, 4),
1025                         inner_str(4, 8),
1026                         quote(8, 9)
1027                     ])
1028                 ])
1029             ]
1030         };
1031     }
1032 
1033     #[test]
range()1034     fn range() {
1035         parses_to! {
1036             parser: PestParser,
1037             input: "'\\n' .. '\\x1a'",
1038             rule: Rule::range,
1039             tokens: [
1040                 range(0, 14, [
1041                     character(0, 4, [
1042                         single_quote(0, 1),
1043                         inner_chr(1, 3),
1044                         single_quote(3, 4)
1045                     ]),
1046                     range_operator(5, 7),
1047                     character(8, 14, [
1048                         single_quote(8, 9),
1049                         inner_chr(9, 13),
1050                         single_quote(13, 14)
1051                     ])
1052                 ])
1053             ]
1054         };
1055     }
1056 
1057     #[test]
character()1058     fn character() {
1059         parses_to! {
1060             parser: PestParser,
1061             input: "'\\u{123abC}'",
1062             rule: Rule::character,
1063             tokens: [
1064                 character(0, 12, [
1065                     single_quote(0, 1),
1066                     inner_chr(1, 11),
1067                     single_quote(11, 12)
1068                 ])
1069             ]
1070         };
1071     }
1072 
1073     #[test]
number()1074     fn number() {
1075         parses_to! {
1076             parser: PestParser,
1077             input: "0123",
1078             rule: Rule::number,
1079             tokens: [
1080                 number(0, 4)
1081             ]
1082         };
1083     }
1084 
1085     #[test]
comment()1086     fn comment() {
1087         parses_to! {
1088             parser: PestParser,
1089             input: "a ~    // asda\n b",
1090             rule: Rule::expression,
1091             tokens: [
1092                 expression(0, 17, [
1093                     term(0, 2, [
1094                         identifier(0, 1)
1095                     ]),
1096                     sequence_operator(2, 3),
1097                     term(16, 17, [
1098                         identifier(16, 17)
1099                     ])
1100                 ])
1101             ]
1102         };
1103     }
1104 
1105     #[test]
grammar_doc_and_line_doc()1106     fn grammar_doc_and_line_doc() {
1107         let input = "//! hello\n/// world\na = { \"a\" }";
1108         parses_to! {
1109             parser: PestParser,
1110             input: input,
1111             rule: Rule::grammar_rules,
1112             tokens: [
1113                 grammar_doc(0, 9, [
1114                     inner_doc(4, 9),
1115                 ]),
1116                 grammar_rule(10, 19, [
1117                     line_doc(10, 19, [
1118                         inner_doc(14, 19),
1119                     ]),
1120                 ]),
1121                 grammar_rule(20, 31, [
1122                     identifier(20, 21),
1123                     assignment_operator(22, 23),
1124                     opening_brace(24, 25),
1125                     expression(26, 30, [
1126                         term(26, 30, [
1127                             string(26, 29, [
1128                                 quote(26, 27),
1129                                 inner_str(27, 28),
1130                                 quote(28, 29)
1131                             ])
1132                         ])
1133                     ]),
1134                     closing_brace(30, 31),
1135                 ])
1136             ]
1137         };
1138     }
1139 
1140     #[test]
wrong_identifier()1141     fn wrong_identifier() {
1142         fails_with! {
1143             parser: PestParser,
1144             input: "0",
1145             rule: Rule::grammar_rules,
1146             positives: vec![Rule::grammar_rule, Rule::grammar_doc],
1147             negatives: vec![],
1148             pos: 0
1149         };
1150     }
1151 
1152     #[test]
missing_assignment_operator()1153     fn missing_assignment_operator() {
1154         fails_with! {
1155             parser: PestParser,
1156             input: "a {}",
1157             rule: Rule::grammar_rules,
1158             positives: vec![Rule::assignment_operator],
1159             negatives: vec![],
1160             pos: 2
1161         };
1162     }
1163 
1164     #[test]
wrong_modifier()1165     fn wrong_modifier() {
1166         fails_with! {
1167             parser: PestParser,
1168             input: "a = *{}",
1169             rule: Rule::grammar_rules,
1170             positives: vec![
1171                 Rule::opening_brace,
1172                 Rule::silent_modifier,
1173                 Rule::atomic_modifier,
1174                 Rule::compound_atomic_modifier,
1175                 Rule::non_atomic_modifier
1176             ],
1177             negatives: vec![],
1178             pos: 4
1179         };
1180     }
1181 
1182     #[test]
missing_opening_brace()1183     fn missing_opening_brace() {
1184         fails_with! {
1185             parser: PestParser,
1186             input: "a = _",
1187             rule: Rule::grammar_rules,
1188             positives: vec![Rule::opening_brace],
1189             negatives: vec![],
1190             pos: 5
1191         };
1192     }
1193 
1194     #[test]
empty_rule()1195     fn empty_rule() {
1196         fails_with! {
1197             parser: PestParser,
1198             input: "a = {}",
1199             rule: Rule::grammar_rules,
1200             positives: vec![Rule::expression],
1201             negatives: vec![],
1202             pos: 5
1203         };
1204     }
1205 
1206     #[test]
missing_rhs()1207     fn missing_rhs() {
1208         fails_with! {
1209             parser: PestParser,
1210             input: "a = { b ~ }",
1211             rule: Rule::grammar_rules,
1212             positives: vec![Rule::term],
1213             negatives: vec![],
1214             pos: 10
1215         };
1216     }
1217 
1218     #[test]
incorrect_prefix()1219     fn incorrect_prefix() {
1220         fails_with! {
1221             parser: PestParser,
1222             input: "a = { ~ b}",
1223             rule: Rule::grammar_rules,
1224             positives: vec![Rule::expression],
1225             negatives: vec![],
1226             pos: 6
1227         };
1228     }
1229 
1230     #[test]
wrong_op()1231     fn wrong_op() {
1232         fails_with! {
1233             parser: PestParser,
1234             input: "a = { b % }",
1235             rule: Rule::grammar_rules,
1236             positives: vec![
1237                 Rule::opening_brace,
1238                 Rule::closing_brace,
1239                 Rule::sequence_operator,
1240                 Rule::choice_operator,
1241                 Rule::optional_operator,
1242                 Rule::repeat_operator,
1243                 Rule::repeat_once_operator
1244             ],
1245             negatives: vec![],
1246             pos: 8
1247         };
1248     }
1249 
1250     #[test]
missing_closing_paren()1251     fn missing_closing_paren() {
1252         fails_with! {
1253             parser: PestParser,
1254             input: "a = { (b }",
1255             rule: Rule::grammar_rules,
1256             positives: vec![
1257                 Rule::opening_brace,
1258                 Rule::closing_paren,
1259                 Rule::sequence_operator,
1260                 Rule::choice_operator,
1261                 Rule::optional_operator,
1262                 Rule::repeat_operator,
1263                 Rule::repeat_once_operator
1264             ],
1265             negatives: vec![],
1266             pos: 9
1267         };
1268     }
1269 
1270     #[test]
missing_term()1271     fn missing_term() {
1272         fails_with! {
1273             parser: PestParser,
1274             input: "a = { ! }",
1275             rule: Rule::grammar_rules,
1276             positives: vec![
1277                 Rule::opening_paren,
1278                 Rule::positive_predicate_operator,
1279                 Rule::negative_predicate_operator,
1280                 Rule::_push,
1281                 Rule::peek_slice,
1282                 Rule::identifier,
1283                 Rule::insensitive_string,
1284                 Rule::quote,
1285                 Rule::single_quote
1286             ],
1287             negatives: vec![],
1288             pos: 8
1289         };
1290     }
1291 
1292     #[test]
string_missing_ending_quote()1293     fn string_missing_ending_quote() {
1294         fails_with! {
1295             parser: PestParser,
1296             input: "a = { \" }",
1297             rule: Rule::grammar_rules,
1298             positives: vec![Rule::quote],
1299             negatives: vec![],
1300             pos: 9
1301         };
1302     }
1303 
1304     #[test]
insensitive_missing_string()1305     fn insensitive_missing_string() {
1306         fails_with! {
1307             parser: PestParser,
1308             input: "a = { ^ }",
1309             rule: Rule::grammar_rules,
1310             positives: vec![Rule::quote],
1311             negatives: vec![],
1312             pos: 8
1313         };
1314     }
1315 
1316     #[test]
char_missing_ending_single_quote()1317     fn char_missing_ending_single_quote() {
1318         fails_with! {
1319             parser: PestParser,
1320             input: "a = { \' }",
1321             rule: Rule::grammar_rules,
1322             positives: vec![Rule::single_quote],
1323             negatives: vec![],
1324             pos: 8
1325         };
1326     }
1327 
1328     #[test]
range_missing_range_operator()1329     fn range_missing_range_operator() {
1330         fails_with! {
1331             parser: PestParser,
1332             input: "a = { \'a\' }",
1333             rule: Rule::grammar_rules,
1334             positives: vec![Rule::range_operator],
1335             negatives: vec![],
1336             pos: 10
1337         };
1338     }
1339 
1340     #[test]
wrong_postfix()1341     fn wrong_postfix() {
1342         fails_with! {
1343             parser: PestParser,
1344             input: "a = { a& }",
1345             rule: Rule::grammar_rules,
1346             positives: vec![
1347                 Rule::opening_brace,
1348                 Rule::closing_brace,
1349                 Rule::sequence_operator,
1350                 Rule::choice_operator,
1351                 Rule::optional_operator,
1352                 Rule::repeat_operator,
1353                 Rule::repeat_once_operator
1354             ],
1355             negatives: vec![],
1356             pos: 7
1357         };
1358     }
1359 
1360     #[test]
ast()1361     fn ast() {
1362         let input = r##"
1363         /// This is line comment
1364         /// This is rule
1365         rule = _{ a{1} ~ "a"{3,} ~ b{, 2} ~ "b"{1, 2} | !(^"c" | PUSH('d'..'e'))?* }
1366         "##;
1367 
1368         let pairs = PestParser::parse(Rule::grammar_rules, input).unwrap();
1369         let ast = consume_rules_with_spans(pairs).unwrap();
1370         let ast: Vec<_> = ast.into_iter().map(convert_rule).collect();
1371 
1372         assert_eq!(
1373             ast,
1374             vec![AstRule {
1375                 name: "rule".to_owned(),
1376                 ty: RuleType::Silent,
1377                 expr: Expr::Choice(
1378                     Box::new(Expr::Seq(
1379                         Box::new(Expr::Seq(
1380                             Box::new(Expr::Seq(
1381                                 Box::new(Expr::RepExact(Box::new(Expr::Ident("a".to_owned())), 1)),
1382                                 Box::new(Expr::RepMin(Box::new(Expr::Str("a".to_owned())), 3))
1383                             )),
1384                             Box::new(Expr::RepMax(Box::new(Expr::Ident("b".to_owned())), 2))
1385                         )),
1386                         Box::new(Expr::RepMinMax(Box::new(Expr::Str("b".to_owned())), 1, 2))
1387                     )),
1388                     Box::new(Expr::NegPred(Box::new(Expr::Rep(Box::new(Expr::Opt(
1389                         Box::new(Expr::Choice(
1390                             Box::new(Expr::Insens("c".to_owned())),
1391                             Box::new(Expr::Push(Box::new(Expr::Range(
1392                                 "d".to_owned(),
1393                                 "e".to_owned()
1394                             ))))
1395                         ))
1396                     ))))))
1397                 )
1398             },]
1399         );
1400     }
1401 
1402     #[test]
ast_peek_slice()1403     fn ast_peek_slice() {
1404         let input = "rule = _{ PEEK[-04..] ~ PEEK[..3] }";
1405 
1406         let pairs = PestParser::parse(Rule::grammar_rules, input).unwrap();
1407         let ast = consume_rules_with_spans(pairs).unwrap();
1408         let ast: Vec<_> = ast.into_iter().map(convert_rule).collect();
1409 
1410         assert_eq!(
1411             ast,
1412             vec![AstRule {
1413                 name: "rule".to_owned(),
1414                 ty: RuleType::Silent,
1415                 expr: Expr::Seq(
1416                     Box::new(Expr::PeekSlice(-4, None)),
1417                     Box::new(Expr::PeekSlice(0, Some(3))),
1418                 ),
1419             }],
1420         );
1421     }
1422 
1423     #[test]
1424     #[should_panic(expected = "grammar error
1425 
1426  --> 1:13
1427   |
1428 1 | rule = { \"\"{4294967297} }
1429   |             ^--------^
1430   |
1431   = number cannot overflow u32")]
repeat_exact_overflow()1432     fn repeat_exact_overflow() {
1433         let input = "rule = { \"\"{4294967297} }";
1434 
1435         let pairs = PestParser::parse(Rule::grammar_rules, input).unwrap();
1436         unwrap_or_report(consume_rules_with_spans(pairs));
1437     }
1438 
1439     #[test]
1440     #[should_panic(expected = "grammar error
1441 
1442  --> 1:13
1443   |
1444 1 | rule = { \"\"{0} }
1445   |             ^
1446   |
1447   = cannot repeat 0 times")]
repeat_exact_zero()1448     fn repeat_exact_zero() {
1449         let input = "rule = { \"\"{0} }";
1450 
1451         let pairs = PestParser::parse(Rule::grammar_rules, input).unwrap();
1452         unwrap_or_report(consume_rules_with_spans(pairs));
1453     }
1454 
1455     #[test]
1456     #[should_panic(expected = "grammar error
1457 
1458  --> 1:13
1459   |
1460 1 | rule = { \"\"{4294967297,} }
1461   |             ^--------^
1462   |
1463   = number cannot overflow u32")]
repeat_min_overflow()1464     fn repeat_min_overflow() {
1465         let input = "rule = { \"\"{4294967297,} }";
1466 
1467         let pairs = PestParser::parse(Rule::grammar_rules, input).unwrap();
1468         unwrap_or_report(consume_rules_with_spans(pairs));
1469     }
1470 
1471     #[test]
1472     #[should_panic(expected = "grammar error
1473 
1474  --> 1:14
1475   |
1476 1 | rule = { \"\"{,4294967297} }
1477   |              ^--------^
1478   |
1479   = number cannot overflow u32")]
repeat_max_overflow()1480     fn repeat_max_overflow() {
1481         let input = "rule = { \"\"{,4294967297} }";
1482 
1483         let pairs = PestParser::parse(Rule::grammar_rules, input).unwrap();
1484         unwrap_or_report(consume_rules_with_spans(pairs));
1485     }
1486 
1487     #[test]
1488     #[should_panic(expected = "grammar error
1489 
1490  --> 1:14
1491   |
1492 1 | rule = { \"\"{,0} }
1493   |              ^
1494   |
1495   = cannot repeat 0 times")]
repeat_max_zero()1496     fn repeat_max_zero() {
1497         let input = "rule = { \"\"{,0} }";
1498 
1499         let pairs = PestParser::parse(Rule::grammar_rules, input).unwrap();
1500         unwrap_or_report(consume_rules_with_spans(pairs));
1501     }
1502 
1503     #[test]
1504     #[should_panic(expected = "grammar error
1505 
1506  --> 1:13
1507   |
1508 1 | rule = { \"\"{4294967297,4294967298} }
1509   |             ^--------^
1510   |
1511   = number cannot overflow u32")]
repeat_min_max_overflow()1512     fn repeat_min_max_overflow() {
1513         let input = "rule = { \"\"{4294967297,4294967298} }";
1514 
1515         let pairs = PestParser::parse(Rule::grammar_rules, input).unwrap();
1516         unwrap_or_report(consume_rules_with_spans(pairs));
1517     }
1518 
1519     #[test]
1520     #[should_panic(expected = "grammar error
1521 
1522  --> 1:15
1523   |
1524 1 | rule = { \"\"{0,0} }
1525   |               ^
1526   |
1527   = cannot repeat 0 times")]
repeat_min_max_zero()1528     fn repeat_min_max_zero() {
1529         let input = "rule = { \"\"{0,0} }";
1530 
1531         let pairs = PestParser::parse(Rule::grammar_rules, input).unwrap();
1532         unwrap_or_report(consume_rules_with_spans(pairs));
1533     }
1534 
1535     #[test]
unescape_all()1536     fn unescape_all() {
1537         let string = r"a\nb\x55c\u{111}d";
1538 
1539         assert_eq!(unescape(string), Some("a\nb\x55c\u{111}d".to_owned()));
1540     }
1541 
1542     #[test]
unescape_empty_escape()1543     fn unescape_empty_escape() {
1544         let string = r"\";
1545 
1546         assert_eq!(unescape(string), None);
1547     }
1548 
1549     #[test]
unescape_wrong_escape()1550     fn unescape_wrong_escape() {
1551         let string = r"\w";
1552 
1553         assert_eq!(unescape(string), None);
1554     }
1555 
1556     #[test]
unescape_backslash()1557     fn unescape_backslash() {
1558         let string = "\\\\";
1559         assert_eq!(unescape(string), Some("\\".to_owned()));
1560     }
1561 
1562     #[test]
1563     fn unescape_return() {
1564         let string = "\\r";
1565         assert_eq!(unescape(string), Some("\r".to_owned()));
1566     }
1567 
1568     #[test]
1569     fn unescape_tab() {
1570         let string = "\\t";
1571         assert_eq!(unescape(string), Some("\t".to_owned()));
1572     }
1573 
1574     #[test]
1575     fn unescape_null() {
1576         let string = "\\0";
1577         assert_eq!(unescape(string), Some("\0".to_owned()));
1578     }
1579 
1580     #[test]
1581     fn unescape_single_quote() {
1582         let string = "\\'";
1583         assert_eq!(unescape(string), Some("\'".to_owned()));
1584     }
1585 
1586     #[test]
1587     fn unescape_wrong_byte() {
1588         let string = r"\xfg";
1589 
1590         assert_eq!(unescape(string), None);
1591     }
1592 
1593     #[test]
1594     fn unescape_short_byte() {
1595         let string = r"\xf";
1596 
1597         assert_eq!(unescape(string), None);
1598     }
1599 
1600     #[test]
1601     fn unescape_no_open_brace_unicode() {
1602         let string = r"\u11";
1603 
1604         assert_eq!(unescape(string), None);
1605     }
1606 
1607     #[test]
1608     fn unescape_no_close_brace_unicode() {
1609         let string = r"\u{11";
1610 
1611         assert_eq!(unescape(string), None);
1612     }
1613 
1614     #[test]
1615     fn unescape_short_unicode() {
1616         let string = r"\u{1}";
1617 
1618         assert_eq!(unescape(string), None);
1619     }
1620 
1621     #[test]
1622     fn unescape_long_unicode() {
1623         let string = r"\u{1111111}";
1624 
1625         assert_eq!(unescape(string), None);
1626     }
1627 
1628     #[test]
1629     fn handles_deep_nesting() {
1630         let sample1 = include_str!(concat!(
1631             env!("CARGO_MANIFEST_DIR"),
1632             "/resources/test/fuzzsample1.grammar"
1633         ));
1634         let sample2 = include_str!(concat!(
1635             env!("CARGO_MANIFEST_DIR"),
1636             "/resources/test/fuzzsample2.grammar"
1637         ));
1638         let sample3 = include_str!(concat!(
1639             env!("CARGO_MANIFEST_DIR"),
1640             "/resources/test/fuzzsample3.grammar"
1641         ));
1642         let sample4 = include_str!(concat!(
1643             env!("CARGO_MANIFEST_DIR"),
1644             "/resources/test/fuzzsample4.grammar"
1645         ));
1646         let sample5 = include_str!(concat!(
1647             env!("CARGO_MANIFEST_DIR"),
1648             "/resources/test/fuzzsample5.grammar"
1649         ));
1650         const ERROR: &str = "call limit reached";
1651         pest::set_call_limit(Some(5_000usize.try_into().unwrap()));
1652         let s1 = parse(Rule::grammar_rules, sample1);
1653         assert!(s1.is_err());
1654         assert_eq!(s1.unwrap_err().variant.message(), ERROR);
1655         let s2 = parse(Rule::grammar_rules, sample2);
1656         assert!(s2.is_err());
1657         assert_eq!(s2.unwrap_err().variant.message(), ERROR);
1658         let s3 = parse(Rule::grammar_rules, sample3);
1659         assert!(s3.is_err());
1660         assert_eq!(s3.unwrap_err().variant.message(), ERROR);
1661         let s4 = parse(Rule::grammar_rules, sample4);
1662         assert!(s4.is_err());
1663         assert_eq!(s4.unwrap_err().variant.message(), ERROR);
1664         let s5 = parse(Rule::grammar_rules, sample5);
1665         assert!(s5.is_err());
1666         assert_eq!(s5.unwrap_err().variant.message(), ERROR);
1667     }
1668 }
1669