lib/regexp-examples/parser.rb in regexp-examples-1.1.2 vs lib/regexp-examples/parser.rb in regexp-examples-1.1.3

- old
+ new

@@ -13,11 +13,11 @@ def parse repeaters = [] until end_of_regexp group = parse_group(repeaters) - return [OneTimeRepeater.new(group)] if group.is_a? OrGroup + return [group] if group.is_a? OrGroup @current_position += 1 repeaters << parse_repeater(group) end repeaters end @@ -118,11 +118,11 @@ when rest_of_string =~ /\A(c|C-)(.)/ # Control character @current_position += Regexp.last_match(1).length group = parse_single_char_group(parse_control_character(Regexp.last_match(2))) when rest_of_string =~ /\Ax(\h{1,2})/ # Escape sequence @current_position += Regexp.last_match(1).length - group = parse_single_char_group(parse_escape_sequence(Regexp.last_match(1))) + group = parse_single_char_group(parse_unicode_sequence(Regexp.last_match(1))) when rest_of_string =~ /\Au(\h{4}|\{\h{1,4}\})/ # Unicode sequence @current_position += Regexp.last_match(1).length sequence = Regexp.last_match(1).match(/\h{1,4}/)[0] # Strip off "{" and "}" group = parse_single_char_group(parse_unicode_sequence(sequence)) when rest_of_string =~ /\A(p)\{(\^?)([^}]+)\}/i # Named properties @@ -146,21 +146,22 @@ ["\r\n", "\n", "\v", "\f", "\r"], @ignorecase ) # Using "\r\n" as one character is little bit hacky... when next_char == 'g' # Subexpression call fail IllegalSyntaxError, - 'Subexpression calls (\\g) cannot be supported, as they are not regular' + 'Subexpression calls (\\g) cannot be supported, as they are not regular' when next_char =~ /[bB]/ # Anchors raise_anchors_exception! when next_char =~ /[AG]/ # Start of string if @current_position == 1 group = PlaceHolderGroup.new else raise_anchors_exception! end when next_char =~ /[zZ]/ # End of string if @current_position == (regexp_string.length - 1) + # TODO: /\Z/ should be treated as /\n?/ group = PlaceHolderGroup.new else raise_anchors_exception! end else @@ -210,14 +211,14 @@ else return PlaceHolderGroup.new end when %w(! =).include?(match[2]) # e.g. /(?=lookahead)/, /(?!neglookahead)/ fail IllegalSyntaxError, - 'Lookaheads are not regular; cannot generate examples' + 'Lookaheads are not regular; cannot generate examples' when %w(! =).include?(match[3]) # e.g. /(?<=lookbehind)/, /(?<!neglookbehind)/ fail IllegalSyntaxError, - 'Lookbehinds are not regular; cannot generate examples' + 'Lookbehinds are not regular; cannot generate examples' else # e.g. /(?<name>namedgroup)/ @current_position += (match[3].length + 3) group_id = match[3] end end @@ -235,18 +236,20 @@ @extended = previous_extended group end def regexp_options_toggle(on, off) - @ignorecase = true if on.include? 'i' - @ignorecase = false if off.include? 'i' - @multiline = true if on.include? 'm' - @multiline = false if off.include? 'm' - @extended = true if on.include? 'x' - @extended = false if off.include? 'x' + regexp_option_toggle(on, off, '@ignorecase', 'i') + regexp_option_toggle(on, off, '@multiline', 'm') + regexp_option_toggle(on, off, '@extended', 'x') end + def regexp_option_toggle(on, off, var, char) + instance_variable_set(var, true) if on.include? char + instance_variable_set(var, false) if off.include? char + end + def parse_char_group @current_position += 1 # Skip past opening "[" chargroup_parser = ChargroupParser.new(rest_of_string) parsed_chars = chargroup_parser.result @current_position += (chargroup_parser.length - 1) # Step back to closing "]" @@ -274,16 +277,12 @@ def parse_control_character(char) (char.ord % 32).chr # Black magic! # eval "?\\C-#{char.chr}" # Doesn't work for e.g. char = "?" end - def parse_escape_sequence(match) - eval "?\\x#{match}" - end - def parse_unicode_sequence(match) - eval "?\\u{#{match}}" + [match.to_i(16)].pack('U') end def parse_star_repeater(group) @current_position += 1 parse_reluctant_or_possessive_repeater @@ -329,10 +328,10 @@ repeater end def raise_anchors_exception! fail IllegalSyntaxError, - "Anchors ('#{next_char}') cannot be supported, as they are not regular" + "Anchors ('#{next_char}') cannot be supported, as they are not regular" end def parse_one_time_repeater(group) OneTimeRepeater.new(group) end