class List::Matcher::Sequence

Public Class Methods

new(engine, *constituents) click to toggle source
Calls superclass method List::Matcher::Node::new
# File lib/list_matcher.rb, line 563
def initialize(engine, *constituents)
  super(engine, nil)
  @children = constituents
end

Public Instance Methods

atomy?(s) click to toggle source

infer atomic patterns

# File lib/list_matcher.rb, line 621
def atomy?(s)
  s.size == 1 || /\A(?>\\\w|\[(?>[^\[\]\\]|\\.)++\])\z/ === s
end
condense(elements) click to toggle source

iterated repeat condensation

# File lib/list_matcher.rb, line 626
def condense(elements)
  while elements.size > 1
    condensate = condense_repeats elements
    break if condensate == elements
    elements = condensate
  end
  elements.join
end
condense_repeats(elements) click to toggle source

looks for repeating subsequences, as in ababababab, and condenses them to (?>ab){5} condensation is only done when it results in a more compact regex

# File lib/list_matcher.rb, line 586
def condense_repeats(elements)
  (1..(elements.size/2)).each do |l|            # length of subsequence considered
    (0...l).each do |o|                         # offset from the start of the sequence
      dup_count = []
      (1...(elements.size - o)/l).each do |s|   # the sub-sequence number
        s2 = s * l + o
        s1 = s2 - l
        seq1 = elements[s1...s1 + l]
        seq2 = elements[s2...s2 + l]
        if seq1 == seq2
          s0 = s - 1
          counts = dup_count[s] = dup_count[s0] || [ 1, seq1.join, s1, nil ]
          counts[0] += 1
          counts[3]  = s2 + l
          dup_count[s0] = nil
        end
      end
      dup_count.compact!
      if dup_count.any?
        copy = elements.dup
        dup_count.reverse.each do |repeats, seq, start, finish|
          a  = atomy? seq
          sl = seq.length
          if ( a ? 0 : engine.wrap_size ) + 2 + repeats.to_s.length + sl < sl * repeats
            copy[start...finish] = ( a ? seq : wrap(seq) ) + "{#{repeats}}"
            return copy;
          end
        end
      end
    end
  end
  elements
end
convert() click to toggle source
# File lib/list_matcher.rb, line 568
def convert
  rx = condense children.map(&:convert)
  finalize rx
end
flatten() click to toggle source
Calls superclass method List::Matcher::Node#flatten
# File lib/list_matcher.rb, line 573
def flatten
  super
  (0...children.size).to_a.reverse.each do |i|
    c = children[i]
    if c.is_a?(Sequence) && !c.optional?
      children.delete_at i
      children.insert i, *c.children
    end
  end
end