lib/arugula/parser.rb in arugula-0.3.0 vs lib/arugula/parser.rb in arugula-0.4.0
- old
+ new
@@ -28,21 +28,25 @@
def consume
tok = pattern.slice!(0)
peek = pattern.chr
if tok.nil?
fail 'shouldnt happen'
- elsif tok == '['
+ elsif tok == '[' && !characterclass_type?
push_part(:characterclass)
elsif tok == '-' &&
characterclass_type? &&
state.parts.last.class.type == :literal &&
peek != ']'
literal = state.parts.pop
push_part(:range, literal.literal, peek)
pattern.slice!(0)
elsif tok == ']' && characterclass_type?
pop_part
+ elsif tok == '^' && characterclass_type? && state.parts.empty?
+ characterclass_part = pop_part
+ wrap_state(:not)
+ @states << characterclass_part
elsif tok == '$'
push_part(:eol)
elsif tok == '^'
push_part(:sol)
elsif tok == '\\'
@@ -70,10 +74,28 @@
push_part(:dot)
elsif tok == '*'
wrap_state(:star)
elsif tok == '+'
wrap_state(:plus)
+ elsif tok == '?'
+ wrap_state(:question)
+ elsif tok == '{'
+ before_comma = ''
+ after_comma = ''
+ until pattern.chr == ',' || pattern.chr == '}'
+ before_comma << pattern.slice!(0)
+ end
+ if pattern.chr == ','
+ pattern.slice!(0)
+ else
+ after_comma = before_comma
+ end
+ after_comma << pattern.slice!(0) until pattern.chr == '}'
+ pattern.slice!(0) if pattern.chr == '}'
+ before = before_comma.empty? ? 0 : before_comma.to_i
+ after = after_comma.empty? ? Float::INFINITY : after_comma.to_i
+ wrap_state(:quantifier, before, after)
else
push_part(:literal, tok)
end
end
@@ -83,11 +105,12 @@
part = part_class.new(*content)
state.parts << part
@states << part unless name == :literal
end
- def wrap_state(name)
- wrapped = Part.all.find { |p| p.type == name }.new(state.parts.pop)
+ def wrap_state(name, *content)
+ wrapped = Part.all.find { |p| p.type == name }
+ .new(*content, state.parts.pop)
state.parts << wrapped
@states << wrapped
end
def pop_part