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, #referential?, #starts_at, #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
# 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
    expressions << exp
  end
end

#dig(*indices) ⇒ Object



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

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
44
45
46
47
48
# File 'lib/regexp_parser/expression/methods/traverse.rb', line 39

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

  block.call(self, 0) if include_self

  each_with_index do |exp, index|
    block.call(exp, index)
    exp.each_expression(&block) unless exp.terminal?
  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.



53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/regexp_parser/expression/methods/traverse.rb', line 53

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



118
119
120
121
122
123
# File 'lib/regexp_parser/expression/methods/match_length.rb', line 118

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



111
112
113
114
115
116
# File 'lib/regexp_parser/expression/methods/match_length.rb', line 111

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



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

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



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

def te
  ts + to_s.length
end

#terminal?Boolean

Returns:

  • (Boolean)


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

def terminal?
  false
end

#to_hObject



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

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