diff options
Diffstat (limited to '')
-rw-r--r-- | vendor/pest_meta/src/optimizer/rotater.rs | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/vendor/pest_meta/src/optimizer/rotater.rs b/vendor/pest_meta/src/optimizer/rotater.rs new file mode 100644 index 000000000..3588738ad --- /dev/null +++ b/vendor/pest_meta/src/optimizer/rotater.rs @@ -0,0 +1,45 @@ +// pest. The Elegant Parser +// Copyright (c) 2018 DragoČ™ Tiselice +// +// Licensed under the Apache License, Version 2.0 +// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT +// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. All files in the project carrying such notice may not be copied, +// modified, or distributed except according to those terms. + +use ast::*; + +pub fn rotate(rule: Rule) -> Rule { + fn rotate_internal(expr: Expr) -> Expr { + match expr { + // TODO: Use box syntax when it gets stabilized. + Expr::Seq(lhs, rhs) => { + let lhs = *lhs; + match lhs { + Expr::Seq(ll, lr) => { + rotate_internal(Expr::Seq(ll, Box::new(Expr::Seq(lr, rhs)))) + } + lhs => Expr::Seq(Box::new(lhs), rhs), + } + } + Expr::Choice(lhs, rhs) => { + let lhs = *lhs; + match lhs { + Expr::Choice(ll, lr) => { + rotate_internal(Expr::Choice(ll, Box::new(Expr::Choice(lr, rhs)))) + } + lhs => Expr::Choice(Box::new(lhs), rhs), + } + } + expr => expr, + } + } + + match rule { + Rule { name, ty, expr } => Rule { + name, + ty, + expr: expr.map_top_down(rotate_internal), + }, + } +} |