lib/arugula/parser.rb in arugula-0.2.1 vs lib/arugula/parser.rb in arugula-0.3.0

- old
+ new

@@ -4,25 +4,26 @@ class Parser attr_reader :pattern def initialize(str) @pattern = str.dup @states = [AndPart.new] + @captures = [] end def state @states.reverse_each.find { |s| s.respond_to?(:parts) } end def parse! consume until pattern.empty? - @states.first + [@states.first, @captures] end Part.all.each do |part| type = part.type define_method(:"#{type}_type?") do - state && state.class.type == type + return true if state && state.class.type == type end end def consume tok = pattern.slice!(0) @@ -54,10 +55,19 @@ else push_part(:literal, tok) end elsif characterclass_type? push_part(:literal, tok) + elsif tok == '(' + push_capture + elsif tok == ')' + pop_part until capture_type? + pop_part + elsif tok == '|' + pop_part until state == @states.first || or_type? || capture_type? + wrap_state(:or) unless or_type? + push_part(:and) elsif tok == '.' push_part(:dot) elsif tok == '*' wrap_state(:star) elsif tok == '+' @@ -82,8 +92,14 @@ end def pop_part @states.pop until @states.last.respond_to?(:parts) @states.pop + end + + def push_capture + push_part(:capture, @captures.size.succ.to_s) + @captures << state + push_part(:and) end end end