Class: Regexp::Expression::Subexpression

Inherits:
Base
  • Object
show all
Defined in:
lib/regexp_parser/expression/subexpression.rb,
lib/regexp_parser/expression/methods/traverse.rb,
lib/regexp_parser/expression/methods/strfregexp.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?, #case_insensitive?, #coded_offset, #default_classes?, #free_spacing?, #full_length, #greedy?, #is?, #match, #matches?, #multiline?, #offset, #one_of?, #possessive?, #quantified?, #quantifier_affix, #quantify, #quantity, #reluctant?, #strfregexp, #terminal?, #to_re, #type?, #unicode_classes?

Constructor Details

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

Returns a new instance of Subexpression.



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

def initialize(token, options = {})
  super

  self.expressions = []
end

Instance Attribute Details

#expressionsObject

Returns the value of attribute expressions.



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

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



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

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

#each_expression(include_self = false, &block) ⇒ 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
# File 'lib/regexp_parser/expression/methods/traverse.rb', line 39

def each_expression(include_self = false, &block)
  traverse(include_self) do |event, exp, index|
    yield(exp, index) unless event == :exit
  end
end

#flat_map(include_self = false, &block) ⇒ 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.



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

def flat_map(include_self = false, &block)
  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(other) ⇒ 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_clone(other)
  other.expressions = expressions.map(&:clone)
  super
end

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



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

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



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

def te
  ts + to_s.length
end

#to_hObject



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

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

#to_s(format = :full) ⇒ Object



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

def to_s(format = :full)
  # Note: the format does not get passed down to subexpressions.
  # Note: cant use #text accessor, b/c it is overriden as def text; to_s end
  # in Expression::Sequence, causing infinite recursion. Clean-up needed.
  "#{@text}#{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)
  raise 'traverse requires a block' 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