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