summaryrefslogtreecommitdiffstats
path: root/vendor/pest_meta/src/optimizer/rotater.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/pest_meta/src/optimizer/rotater.rs')
-rw-r--r--vendor/pest_meta/src/optimizer/rotater.rs45
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),
+ },
+ }
+}