Class: Regexp::Expression::Subexpression

Inherits:
Base
  • Object
show all
Includes:
Enumerable
Defined in:
lib/regexp_parser/expression/subexpression.rb,
lib/regexp_parser/expression/methods/traverse.rb,
lib/regexp_parser/expression/methods/strfregexp.rb,
lib/regexp_parser/expression/methods/match_length.rb

Instance Attribute Summary collapse

Attributes inherited from Base

#conditional_level, #level, #nesting_level, #options, #quantifier, #set_level, #text, #token, #ts, #type

Instance Method Summary collapse

Methods inherited from Base

#ascii_classes?, #attributes, #base_length, #case_insensitive?, #coded_offset, #default_classes?, #free_spacing?, #full_length, #greedy?, #is?, #match, #match?, #multiline?, #offset, #one_of?, #possessive?, #quantified?, #quantifier_affix, #quantify, #quantity, #reluctant?, #repetitions, #strfregexp, #terminal?, #to_re, #type?, #unicode_classes?, #unquantified_clone

Constructor Details

#initialize(token, options = {}) ⇒ Subexpression

Returns a new instance of Subexpression.



8
9
10
11
12
# File 'lib/regexp_parser/expression/subexpression.rb', line 8

def initialize(token, options = {})
  super

  self.expressions = []
end

Instance Attribute Details

#expressionsObject

Returns the value of attribute expressions.



6
7
8
# File 'lib/regexp_parser/expression/subexpression.rb', line 6

def expressions
  @expressions
end

Instance Method Details

#<<(exp) ⇒ Object



20
21
22
23
24
25
26
27
# File 'lib/regexp_parser/expression/subexpression.rb', line 20

def <<(exp)
  if exp.is_a?(WhiteSpace) && last && last.is_a?(WhiteSpace)
    last.merge(exp)
  else
    exp.nesting_level = nesting_level + 1
    expressions << exp
  end
end

#dig(*indices) ⇒ Object



37
38
39
40
41
# File 'lib/regexp_parser/expression/subexpression.rb', line 37

def dig(*indices)
  exp = self
  indices.each { |idx| exp = exp.nil? || exp.terminal? ? nil : exp[idx] }
  exp
end

#each_expression(include_self = false) ⇒ Object

Iterates over the expressions of this expression as an array, passing the expression and its index within its parent to the given block.



39
40
41
42
43
44
45
# File 'lib/regexp_parser/expression/methods/traverse.rb', line 39

def each_expression(include_self = false)
  return enum_for(__method__, include_self) unless block_given?

  traverse(include_self) do |event, exp, index|
    yield(exp, index) unless event == :exit
  end
end

#flat_map(include_self = false) ⇒ Object

Returns a new array with the results of calling the given block once for every expression. If a block is not given, returns an array with each expression and its level index as an array.



50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/regexp_parser/expression/methods/traverse.rb', line 50

def flat_map(include_self = false)
  result = []

  each_expression(include_self) do |exp, index|
    if block_given?
      result << yield(exp, index)
    else
      result << [exp, index]
    end
  end

  result
end

#initialize_clone(orig) ⇒ Object

Override base method to clone the expressions as well.



15
16
17
18
# File 'lib/regexp_parser/expression/subexpression.rb', line 15

def initialize_clone(orig)
  self.expressions = orig.expressions.map(&:clone)
  super
end

#inner_match_lengthObject



114
115
116
117
118
119
# File 'lib/regexp_parser/expression/methods/match_length.rb', line 114

def inner_match_length
  dummy = Regexp::Expression::Root.build
  dummy.expressions = expressions.map(&:clone)
  dummy.quantifier = quantifier && quantifier.clone
  dummy.match_length
end

#match_lengthObject



107
108
109
110
111
112
# File 'lib/regexp_parser/expression/methods/match_length.rb', line 107

def match_length
  MatchLength.new(self,
                   base_min: map { |exp| exp.match_length.min }.inject(0, :+),
                   base_max: map { |exp| exp.match_length.max }.inject(0, :+),
                   reify: ->{ map { |exp| exp.match_length.to_re }.join })
end

#strfregexp_tree(format = '%a', include_self = true, separator = "\n") ⇒ Object Also known as: strfre_tree



102
103
104
105
106
107
108
109
110
# File 'lib/regexp_parser/expression/methods/strfregexp.rb', line 102

def strfregexp_tree(format = '%a', include_self = true, separator = "\n")
  output = include_self ? [self.strfregexp(format)] : []

  output += flat_map do |exp, index|
    exp.strfregexp(format, (include_self ? 1 : 0), index)
  end

  output.join(separator)
end

#teObject



43
44
45
# File 'lib/regexp_parser/expression/subexpression.rb', line 43

def te
  ts + to_s.length
end

#to_hObject



52
53
54
55
56
57
# File 'lib/regexp_parser/expression/subexpression.rb', line 52

def to_h
  attributes.merge({
    text:        to_s(:base),
    expressions: expressions.map(&:to_h)
  })
end

#to_s(format = :full) ⇒ Object



47
48
49
50
# File 'lib/regexp_parser/expression/subexpression.rb', line 47

def to_s(format = :full)
  # Note: the format does not get passed down to subexpressions.
  "#{expressions.join}#{quantifier_affix(format)}"
end

#traverse(include_self = false, &block) ⇒ Object Also known as: walk

Traverses the subexpression (depth-first, pre-order) and calls the given block for each expression with three arguments; the traversal event, the expression, and the index of the expression within its parent.

The event argument is passed as follows:

  • For subexpressions, :enter upon entering the subexpression, and :exit upon exiting it.

  • For terminal expressions, :visit is called once.

Returns self.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/regexp_parser/expression/methods/traverse.rb', line 16

def traverse(include_self = false, &block)
  return enum_for(__method__, include_self) unless block_given?

  block.call(:enter, self, 0) if include_self

  each_with_index do |exp, index|
    if exp.terminal?
      block.call(:visit, exp, index)
    else
      block.call(:enter, exp, index)
      exp.traverse(&block)
      block.call(:exit, exp, index)
    end
  end

  block.call(:exit, self, 0) if include_self

  self
end