class Regexp::Expression::Subexpression
Attributes
Public Class Methods
Regexp::Expression::Base::new
# File lib/regexp_parser/expression/subexpression.rb, line 7 def initialize(token, options = {}) self.expressions = [] super end
Public Instance Methods
# File lib/regexp_parser/expression/subexpression.rb, line 20 def <<(exp) exp.parent = self expressions << exp end
# File lib/regexp_parser/expression/subexpression.rb, line 33 def dig(*indices) exp = self indices.each { |idx| exp = exp.nil? || exp.terminal? ? nil : exp[idx] } exp end
Traverses the expression, passing each recursive child to the given block. If the block takes two arguments, the indices of the children within their parents are also passed to it.
# File lib/regexp_parser/expression/methods/traverse.rb, line 8 def each_expression(include_self = false, &block) return enum_for(__method__, include_self) unless block if block.arity == 1 block.call(self) if include_self each_expression_without_index(&block) else block.call(self, 0) if include_self each_expression_with_index(&block) end end
# File lib/regexp_parser/expression/subexpression.rb, line 50 def extract_quantifier_target(quantifier_description) pre_quantifier_decorations = [] target = expressions.reverse.find do |exp| if exp.decorative? exp.custom_to_s_handling = true pre_quantifier_decorations << exp.text next end exp end target or raise Regexp::Parser::ParserError, "No valid target found for '#{quantifier_description}' quantifier" target.pre_quantifier_decorations = pre_quantifier_decorations target end
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.
# File lib/regexp_parser/expression/methods/traverse.rb, line 56 def flat_map(include_self = false, &block) case block && block.arity when nil then each_expression(include_self).to_a when 2 then each_expression(include_self).map(&block) else each_expression(include_self).map { |exp| block.call(exp) } end end
Override base method to clone the expressions as well.
Regexp::Expression::Shared#initialize_copy
# File lib/regexp_parser/expression/subexpression.rb, line 13 def initialize_copy(orig) self.expressions = orig.expressions.map do |exp| exp.clone.tap { |copy| copy.parent = self } end super end
# 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
# 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
# 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
# File lib/regexp_parser/expression/subexpression.rb, line 39 def te ts + base_length end
# File lib/regexp_parser/expression/subexpression.rb, line 43 def to_h attributes.merge( text: to_s(:base), expressions: expressions.map(&:to_h) ) end
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.
# File lib/regexp_parser/expression/methods/traverse.rb, line 32 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
Protected Instance Methods
# File lib/regexp_parser/expression/methods/traverse.rb, line 66 def each_expression_with_index(&block) each_with_index do |exp, index| block.call(exp, index) exp.each_expression_with_index(&block) unless exp.terminal? end end
# File lib/regexp_parser/expression/methods/traverse.rb, line 73 def each_expression_without_index(&block) each do |exp| block.call(exp) exp.each_expression_without_index(&block) unless exp.terminal? end end