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?
Included modules
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
# 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
Returns an array of events for this rule on the given input.
# 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
Returns the operator this rule uses as a string. Will be one of +, ?, or N*M.
# 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
Returns the Rule object this rule uses to match.
# File lib/citrus.rb, line 1137 1137: def rule 1138: rules[0] 1139: end