Class: Citrus::Repeat
Overview
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?
Instance Attribute Summary collapse
-
#max ⇒ Object
readonly
The maximum number of times this rule may match.
-
#min ⇒ Object
readonly
The minimum number of times this rule must match.
Attributes included from Nonterminal
Attributes included from Rule
#extension, #grammar, #label, #name
Instance Method Summary collapse
-
#exec(input, events = []) ⇒ Object
Returns an array of events for this rule on the given
input. -
#initialize(rule = '', min = 1, max = Infinity) ⇒ Repeat
constructor
A new instance of Repeat.
-
#operator ⇒ Object
Returns the operator this rule uses as a string.
-
#rule ⇒ Object
Returns the Rule object this rule uses to match.
-
#to_citrus ⇒ Object
Returns the Citrus notation of this rule as a string.
Methods included from Nonterminal
Methods included from Rule
#==, #===, #default_options, #elide?, #extend_match, for, #inspect, #needs_paren?, #parse, #terminal?, #test, #to_embedded_s, #to_s
Constructor Details
#initialize(rule = '', min = 1, max = Infinity) ⇒ Repeat
Returns a new instance of Repeat.
1129 1130 1131 1132 1133 1134 |
# File 'lib/citrus.rb', line 1129 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 |
Instance Attribute Details
#max ⇒ Object (readonly)
The maximum number of times this rule may match.
1169 1170 1171 |
# File 'lib/citrus.rb', line 1169 def max @max end |
#min ⇒ Object (readonly)
The minimum number of times this rule must match.
1166 1167 1168 |
# File 'lib/citrus.rb', line 1166 def min @min end |
Instance Method Details
#exec(input, events = []) ⇒ Object
Returns an array of events for this rule on the given input.
1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 |
# File 'lib/citrus.rb', line 1142 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 ⇒ Object
Returns the operator this rule uses as a string. Will be one of +, ?, or N*M.
1173 1174 1175 1176 1177 1178 1179 1180 1181 |
# File 'lib/citrus.rb', line 1173 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 ⇒ Object
Returns the Rule object this rule uses to match.
1137 1138 1139 |
# File 'lib/citrus.rb', line 1137 def rule rules[0] end |
#to_citrus ⇒ Object
Returns the Citrus notation of this rule as a string.
1184 1185 1186 |
# File 'lib/citrus.rb', line 1184 def to_citrus # :nodoc: rule. + operator end |