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}
56