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

Instance Method Summary collapse

Methods inherited from Base

#ascii_classes?, #case_insensitive?, #default_classes?, #free_spacing?, #greedy?, #match, #match?, #multiline?, #possessive?, #quantify, #quantity, #reluctant?, #repetitions, #strfregexp, #to_re, #unicode_classes?, #unquantified_clone

Methods included from Shared

#==, #base_length, #coded_offset, #full_length, #human_name, included, #is?, #nesting_level=, #offset, #one_of?, #optional?, #quantified?, #quantifier=, #quantifier_affix, #starts_at, #terminal?, #to_s, #token_class, #type?

Constructor Details

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

Returns a new instance of Subexpression.



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

def initialize(token, options = {})
  self.expressions = []
  super
end

Instance Attribute Details

#expressionsObject

Returns the value of attribute expressions.



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

def expressions
  @expressions
end

Instance Method Details

#<<(exp) ⇒ Object



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

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



35
36
37
38
39
# File 'lib/regexp_parser/expression/subexpression.rb', line 35

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_copy(orig) ⇒ Object

Override base method to clone the expressions as well.



13
14
15
16
# File 'lib/regexp_parser/expression/subexpression.rb', line 13

def initialize_copy(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.construct
  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

#partsObject



45
46
47
# File 'lib/regexp_parser/expression/subexpression.rb', line 45

def parts
  expressions
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



41
42
43
# File 'lib/regexp_parser/expression/subexpression.rb', line 41

def te
  ts + to_s.length
end

#to_hObject



49
50
51
52
53
54
# File 'lib/regexp_parser/expression/subexpression.rb', line 49

def to_h
  attributes.merge(
    text:        to_s(:base),
    expressions: expressions.map(&:to_h)
  )
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