Permalink
Browse files

Implements alternative matching

  • Loading branch information...
1 parent ae2e990 commit c1048b1ebdfdfb96c26359f33bb8c51e1e190696 @kschiess committed Jul 30, 2013
Showing with 26 additions and 3 deletions.
  1. +10 −2 lib/parslet/accelerator.rb
  2. +7 −1 lib/parslet/accelerator/engine.rb
  3. +9 −0 qed/accelerators.md
View
@@ -10,10 +10,18 @@ def initialize(type, *args)
end
def >> other_expr
- if type == :seq
+ join_or_new :seq, other_expr
+ end
+
+ def | other_expr
+ join_or_new :alt, other_expr
+ end
+
+ def join_or_new tag, other_expr
+ if type == tag
@args << other_expr
else
- Expression.new(:seq, self, other_expr)
+ Expression.new(tag, self, other_expr)
end
end
end
@@ -21,7 +21,13 @@ def visit_repetition(tag, min, max, atom)
false
end
def visit_alternative(alternatives)
- false
+ match(:alt) do |*expressions|
+ return false if alternatives.size != expressions.size
+
+ alternatives.zip(expressions).all? do |atom, expr|
+ @engine.match(atom, expr)
+ end
+ end
end
def visit_sequence(sequence)
match(:seq) do |*expressions|
View
@@ -125,6 +125,15 @@ Let's start assembling these simple parsers into more complex patterns and match
binding.values_at(:x, :y).assert == %w(a b)
+Also, alternatives should correctly bind.
+
+ binding = Accelerator.match(
+ str('a') | str('b'),
+ Accelerator.str(:x) | Accelerator.str(:y))
+
+ binding.values_at(:x, :y).assert == %w(a b)
+
+Note that this means that we bind to the whole alternative subtree, not either to the left or to the right. We're matching the parslet tree, so the meaning of the alternative is irrelevant.
## Binding to Values

0 comments on commit c1048b1

Please sign in to comment.