pest_meta/optimizer/
skipper.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
10use crate::ast::*;
11
12pub fn skip(rule: Rule) -> Rule {
13    fn populate_choices(expr: Expr, mut choices: Vec<String>) -> Option<Expr> {
14        match expr {
15            Expr::Choice(lhs, rhs) => {
16                if let Expr::Str(string) = *lhs {
17                    choices.push(string);
18                    populate_choices(*rhs, choices)
19                } else {
20                    None
21                }
22            }
23            Expr::Str(string) => {
24                choices.push(string);
25                Some(Expr::Skip(choices))
26            }
27            _ => None,
28        }
29    }
30
31    let Rule { name, ty, expr } = rule;
32    Rule {
33        name,
34        ty,
35        expr: if ty == RuleType::Atomic {
36            expr.map_top_down(|expr| {
37                if let Expr::Rep(expr) = expr.clone() {
38                    if let Expr::Seq(lhs, rhs) = *expr {
39                        if let (Expr::NegPred(expr), Expr::Ident(ident)) = (*lhs, *rhs) {
40                            if ident == "ANY" {
41                                if let Some(expr) = populate_choices(*expr, vec![]) {
42                                    return expr;
43                                }
44                            }
45                        }
46                    }
47                };
48
49                expr
50            })
51        } else {
52            expr
53        },
54    }
55}