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