class Citrus::Repeat

A Repeat is a Nonterminal that specifies a minimum and maximum number of times its rule must match. The Citrus notation is an integer, N, followed by an asterisk, followed by another integer, M, all of which follow any other expression, e.g.:

expr N*M

In this notation N specifies the minimum number of times the preceding expression must match and M specifies the maximum. If N is ommitted, it is assumed to be 0. Likewise, if M is omitted, it is assumed to be infinity (no maximum). Thus, an expression followed by only an asterisk may match any number of times, including zero.

The shorthand notation + and ? may be used for the common cases of 1* and *1 respectively, e.g.:

expr+
expr?

Attributes

max[R]

The maximum number of times this rule may match.

min[R]

The minimum number of times this rule must match.

Public Class Methods

new(rule='', min=1, max=Infinity) click to toggle source
Calls superclass method Citrus::Nonterminal.new
# File lib/citrus.rb, line 1128
def initialize(rule='', min=1, max=Infinity)
  raise ArgumentError, "Min cannot be greater than max" if min > max
  super([rule])
  @min = min
  @max = max
end

Public Instance Methods

exec(input, events=[]) click to toggle source

Returns an array of events for this rule on the given input.

# File lib/citrus.rb, line 1141
def exec(input, events=[])
  events << self

  index = events.size
  start = index - 1
  length = n = 0

  while n < max && input.exec(rule, events).size > index
    length += events[-1]
    index = events.size
    n += 1
  end

  if n >= min
    events << CLOSE
    events << length
  else
    events.slice!(start, index)
  end

  events
end
operator() click to toggle source

Returns the operator this rule uses as a string. Will be one of +, ?, or N*M.

# File lib/citrus.rb, line 1172
def operator
  @operator ||= case [min, max]
    when [0, 0] then ''
    when [0, 1] then '?'
    when [1, Infinity] then '+'
    else
      [min, max].map {|n| n == 0 || n == Infinity ? '' : n.to_s }.join('*')
    end
end
rule() click to toggle source

Returns the Rule object this rule uses to match.

# File lib/citrus.rb, line 1136
def rule
  rules[0]
end