• 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 use ast::*;
11 
factor(rule: Rule) -> Rule12 pub fn factor(rule: Rule) -> Rule {
13     match rule {
14         Rule { name, ty, expr } => Rule {
15             name,
16             ty,
17             expr: expr.map_top_down(|expr| {
18                 // TODO: Use box syntax when it gets stabilized.
19                 match expr {
20                     Expr::Choice(lhs, rhs) => match (*lhs, *rhs) {
21                         (Expr::Seq(l1, r1), Expr::Seq(l2, r2)) => {
22                             if l1 == l2 {
23                                 Expr::Seq(l1, Box::new(Expr::Choice(r1, r2)))
24                             } else {
25                                 Expr::Choice(
26                                     Box::new(Expr::Seq(l1, r1)),
27                                     Box::new(Expr::Seq(l2, r2)),
28                                 )
29                             }
30                         }
31                         (lhs, rhs) => Expr::Choice(Box::new(lhs), Box::new(rhs)),
32                     },
33                     expr => expr,
34                 }
35             }),
36         },
37     }
38 }
39