pest_meta/
parser.rs

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