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