Sha256: a50b34a883d974ede1f7889a356303fce18476e952258f4e3e912d0146ea0eae

Contents?: true

Size: 1.04 KB

Versions: 4

Compression:

Stored size: 1.04 KB

Contents

module Sexpr
  module Matcher
    class Many
      include Matcher

      attr_reader :term, :min, :max

      def initialize(term, min, max = nil)
        @term       = term
        @min, @max  = minmax(min, max)
      end

      def match?(sexp)
        return nil unless sexp.is_a?(Array)
        eat = eat(sexp)
        eat && eat.empty?
      end

      def eat(sexp)
        i, last = 0, sexp
        while sexp && (@max.nil? || i < @max)
          if res = @term.eat(sexp)
            last = res
            i += 1
          end
          sexp = res
        end
        i >= @min ? last : nil
      end

      def inspect
        "(many #{term.inspect}, #{min}, #{max})"
      end

      private

      def minmax(min, max)
        case min
        when Integer
          [min, max]
        when '?'
          [0, 1]
        when '+'
          [1, nil]
        when '*'
          [0, nil]
        else
          raise ArgumentError, "Invalid multiplicity: #{min}"
        end
      end

    end # class Sequence
  end # module Matcher
end # module Sexpr

Version data entries

4 entries across 4 versions & 1 rubygems

Version Path
sexpr-0.5.1 lib/sexpr/matcher/many.rb
sexpr-0.5.0 lib/sexpr/matcher/many.rb
sexpr-0.4.0 lib/sexpr/matcher/many.rb
sexpr-0.3.0 lib/sexpr/matcher/many.rb