Class Citrus::Repeat

  1. lib/citrus.rb
Parent: Object

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?

Methods

public class

  1. new

public instance

  1. exec
  2. operator
  3. rule

Included modules

  1. Nonterminal

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)
[show source]
      # File lib/citrus.rb, line 1129
1129:     def initialize(rule='', min=1, max=Infinity)
1130:       raise ArgumentError, "Min cannot be greater than max" if min > max
1131:       super([rule])
1132:       @min = min
1133:       @max = max
1134:     end

Public instance methods

exec (input, events=[])

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

[show source]
      # File lib/citrus.rb, line 1142
1142:     def exec(input, events=[])
1143:       events << self
1144: 
1145:       index = events.size
1146:       start = index - 1
1147:       length = n = 0
1148: 
1149:       while n < max && input.exec(rule, events).size > index
1150:         length += events[-1]
1151:         index = events.size
1152:         n += 1
1153:       end
1154: 
1155:       if n >= min
1156:         events << CLOSE
1157:         events << length
1158:       else
1159:         events.slice!(start, index)
1160:       end
1161: 
1162:       events
1163:     end
operator ()

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

[show source]
      # File lib/citrus.rb, line 1173
1173:     def operator
1174:       @operator ||= case [min, max]
1175:         when [0, 0] then ''
1176:         when [0, 1] then '?'
1177:         when [1, Infinity] then '+'
1178:         else
1179:           [min, max].map {|n| n == 0 || n == Infinity ? '' : n.to_s }.join('*')
1180:         end
1181:     end
rule ()

Returns the Rule object this rule uses to match.

[show source]
      # File lib/citrus.rb, line 1137
1137:     def rule
1138:       rules[0]
1139:     end