srl_ruby 0.4.6 → 0.4.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +298 -23
- data/CHANGELOG.md +29 -1
- data/LICENSE.txt +1 -1
- data/Rakefile +1 -0
- data/bin/srl2ruby +8 -6
- data/bin/srl2ruby_cli_parser.rb +1 -3
- data/lib/regex/alternation.rb +1 -3
- data/lib/regex/anchor.rb +1 -0
- data/lib/regex/capturing_group.rb +6 -3
- data/lib/regex/char_class.rb +1 -1
- data/lib/regex/char_range.rb +1 -3
- data/lib/regex/char_shorthand.rb +1 -0
- data/lib/regex/character.rb +1 -0
- data/lib/regex/expression.rb +3 -0
- data/lib/regex/lookaround.rb +1 -1
- data/lib/regex/multiplicity.rb +6 -9
- data/lib/regex/non_capturing_group.rb +1 -1
- data/lib/regex/quantifiable.rb +1 -1
- data/lib/regex/wildcard.rb +0 -5
- data/lib/srl_ruby/ast_builder.rb +79 -120
- data/lib/srl_ruby/grammar.rb +78 -92
- data/lib/srl_ruby/tokenizer.rb +6 -2
- data/lib/srl_ruby/version.rb +1 -1
- data/spec/acceptance/support/rule_file_ast_builder.rb +1 -22
- data/spec/acceptance/support/rule_file_grammar.rb +16 -21
- data/spec/acceptance/support/rule_file_tokenizer.rb +6 -1
- data/spec/regex/character_spec.rb +14 -6
- data/spec/regex/multiplicity_spec.rb +2 -0
- data/spec/srl_ruby_spec.rb +6 -6
- data/srl_ruby.gemspec +3 -3
- metadata +11 -11
|
@@ -22,7 +22,7 @@ module Regex # This module is used as a namespace
|
|
|
22
22
|
# Conversion method re-definition.
|
|
23
23
|
# Purpose: Return the String representation of the captured expression.
|
|
24
24
|
def text_repr
|
|
25
|
-
result =
|
|
25
|
+
result = "(?:#{all_child_text})"
|
|
26
26
|
return result
|
|
27
27
|
end
|
|
28
28
|
end # class
|
data/lib/regex/quantifiable.rb
CHANGED
data/lib/regex/wildcard.rb
CHANGED
|
@@ -7,11 +7,6 @@ require_relative 'atomic_expression' # Access the superclass
|
|
|
7
7
|
module Regex # This module is used as a namespace
|
|
8
8
|
# A wildcard matches any character (except for the newline).
|
|
9
9
|
class Wildcard < AtomicExpression
|
|
10
|
-
# Constructor
|
|
11
|
-
def initialize
|
|
12
|
-
super
|
|
13
|
-
end
|
|
14
|
-
|
|
15
10
|
protected
|
|
16
11
|
|
|
17
12
|
# Conversion method re-definition.
|
data/lib/srl_ruby/ast_builder.rb
CHANGED
|
@@ -68,6 +68,8 @@ module SrlRuby
|
|
|
68
68
|
return Regex::Multiplicity.new(lowerBound, upperBound, :greedy)
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
+
# rubocop: disable Style/OptionalBooleanParameter
|
|
72
|
+
|
|
71
73
|
def string_literal(aString, to_escape = true)
|
|
72
74
|
if aString.size > 1
|
|
73
75
|
chars = []
|
|
@@ -88,6 +90,7 @@ module SrlRuby
|
|
|
88
90
|
|
|
89
91
|
return result
|
|
90
92
|
end
|
|
93
|
+
# rubocop: enable Style/OptionalBooleanParameter
|
|
91
94
|
|
|
92
95
|
def char_range(lowerBound, upperBound)
|
|
93
96
|
lower = Regex::Character.new(lowerBound)
|
|
@@ -115,70 +118,52 @@ module SrlRuby
|
|
|
115
118
|
Regex::Anchor.new('^')
|
|
116
119
|
end
|
|
117
120
|
|
|
118
|
-
# rule('expression' =>
|
|
121
|
+
# rule('expression' => 'pattern (flags)?').tag 'flagged_expr'
|
|
119
122
|
def reduce_flagged_expr(_production, aRange, theTokens, theChildren)
|
|
120
|
-
@options = theChildren[1] if theChildren[1]
|
|
123
|
+
@options = theChildren[1].first if theChildren[1]
|
|
121
124
|
return_first_child(aRange, theTokens, theChildren)
|
|
122
125
|
end
|
|
123
126
|
|
|
124
|
-
# rule('pattern' =>
|
|
127
|
+
# rule('pattern' => 'subpattern (separator sub_pattern)*').tag 'pattern_sequence'
|
|
125
128
|
def reduce_pattern_sequence(_production, _range, _tokens, theChildren)
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
+
return theChildren[0] if theChildren[1].empty?
|
|
130
|
+
|
|
131
|
+
successors = theChildren[1].map { |pair| pair[1] }
|
|
132
|
+
if successors[0].kind_of?(Regex::Lookaround) && successors[0].dir == :behind
|
|
133
|
+
Regex::Concatenation.new(successors.shift, theChildren[0], *successors)
|
|
129
134
|
else
|
|
130
|
-
Regex::Concatenation.new(theChildren[0],
|
|
135
|
+
Regex::Concatenation.new(theChildren[0], *successors)
|
|
131
136
|
end
|
|
132
137
|
end
|
|
133
138
|
|
|
134
|
-
# rule('
|
|
135
|
-
def reduce_basic_pattern(_production, aRange, theTokens, theChildren)
|
|
136
|
-
return_first_child(aRange, theTokens, theChildren)
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
# rule('sub_pattern' => 'assertion').as 'assertion_sub_pattern'
|
|
139
|
+
# rule('sub_pattern' => 'assertion').tag 'assertion_sub_pattern'
|
|
140
140
|
def reduce_assertion_sub_pattern(_production, aRange, theTokens, theChildren)
|
|
141
141
|
return_first_child(aRange, theTokens, theChildren)
|
|
142
142
|
end
|
|
143
143
|
|
|
144
|
-
# rule('flags' =>
|
|
144
|
+
# rule('flags' => '(separator single_flag)+').tag 'flag_sequence'
|
|
145
145
|
def reduce_flag_sequence(_production, _range, _tokens, theChildren)
|
|
146
|
-
theChildren[0]
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
# rule('flags' => %w[separator single_flag]).as 'flag_simple'
|
|
150
|
-
def reduce_flag_simple(_production, _range, _tokens, theChildren)
|
|
151
|
-
[theChildren.last]
|
|
146
|
+
theChildren[0].map { |(_, flag)| flag }
|
|
152
147
|
end
|
|
153
148
|
|
|
154
|
-
# rule('single_flag' => %w[CASE INSENSITIVE]).
|
|
149
|
+
# rule('single_flag' => %w[CASE INSENSITIVE]).tag 'case_insensitive'
|
|
155
150
|
def reduce_case_insensitive(_production, _range, _tokens, _children)
|
|
156
151
|
Regexp::IGNORECASE
|
|
157
152
|
end
|
|
158
153
|
|
|
159
|
-
# rule('single_flag' => %w[MULTI LINE]).
|
|
154
|
+
# rule('single_flag' => %w[MULTI LINE]).tag 'multi_line'
|
|
160
155
|
def reduce_multi_line(_production, _range, _tokens, _children)
|
|
161
156
|
Regexp::MULTILINE
|
|
162
157
|
end
|
|
163
158
|
|
|
164
|
-
# rule('single_flag' => %w[ALL LAZY]).
|
|
159
|
+
# rule('single_flag' => %w[ALL LAZY]).tag 'all_lazy'
|
|
165
160
|
def reduce_all_lazy(_production, _range, _tokens, _children)
|
|
166
161
|
:ALL_LAZY
|
|
167
162
|
end
|
|
168
163
|
|
|
169
|
-
# rule
|
|
170
|
-
def
|
|
171
|
-
Regex::Concatenation.new(*theChildren)
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
# rule 'quantifiable' => %w[begin_anchor anchorable]
|
|
175
|
-
def reduce_begin_anchor_quantifiable(_production, _range, _tokens, theChildren)
|
|
176
|
-
Regex::Concatenation.new(*theChildren)
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
# rule 'quantifiable' => %w[anchorable end_anchor]
|
|
180
|
-
def reduce_end_anchor_quantifiable(_production, _range, _tokens, theChildren)
|
|
181
|
-
return Regex::Concatenation.new(*theChildren)
|
|
164
|
+
# rule('quantifiable' => 'begin_anchor? anchorable end_anchor?')
|
|
165
|
+
def reduce_quantifiable(_production, _range, _tokens, theChildren)
|
|
166
|
+
Regex::Concatenation.new(*theChildren.flatten.compact)
|
|
182
167
|
end
|
|
183
168
|
|
|
184
169
|
# rule 'begin_anchor' => %w[STARTS WITH]
|
|
@@ -191,39 +176,30 @@ module SrlRuby
|
|
|
191
176
|
begin_anchor
|
|
192
177
|
end
|
|
193
178
|
|
|
194
|
-
# rule('end_anchor' => %w[separator MUST END]).
|
|
179
|
+
# rule('end_anchor' => %w[separator MUST END]).tag 'end_anchor'
|
|
195
180
|
def reduce_end_anchor(_production, _range, _tokens, _children)
|
|
196
181
|
Regex::Anchor.new('$')
|
|
197
182
|
end
|
|
198
183
|
|
|
199
|
-
# rule('assertion' =>
|
|
184
|
+
# rule('assertion' => 'IF NOT? FOLLOWED BY assertable')
|
|
200
185
|
def reduce_if_followed(_production, _range, _tokens, theChildren)
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
# rule('assertion' => %w[IF NOT FOLLOWED BY assertable]).as 'if_not_followed'
|
|
205
|
-
def reduce_if_not_followed(_production, _range, _tokens, theChildren)
|
|
206
|
-
Regex::Lookaround.new(theChildren.last, :ahead, :negative)
|
|
186
|
+
polarity = theChildren[1] ? :negative : :positive
|
|
187
|
+
Regex::Lookaround.new(theChildren.last, :ahead, polarity)
|
|
207
188
|
end
|
|
208
189
|
|
|
209
|
-
# rule('assertion' =>
|
|
190
|
+
# rule('assertion' => 'IF NOT? ALREADY HAD assertable')
|
|
210
191
|
def reduce_if_had(_production, _range, _tokens, theChildren)
|
|
211
|
-
|
|
192
|
+
polarity = theChildren[1] ? :negative : :positive
|
|
193
|
+
Regex::Lookaround.new(theChildren.last, :behind, polarity)
|
|
212
194
|
end
|
|
213
195
|
|
|
214
|
-
# rule('
|
|
215
|
-
def
|
|
216
|
-
|
|
196
|
+
# rule('assertable' => 'term quantifier?').tag 'assertable'
|
|
197
|
+
def reduce_assertable(_production, _range, _tokens, theChildren)
|
|
198
|
+
(term, quantifier) = theChildren.flatten
|
|
199
|
+
quantifier ? repetition(term, quantifier) : term
|
|
217
200
|
end
|
|
218
201
|
|
|
219
|
-
# rule('
|
|
220
|
-
def reduce_quantified_assertable(_production, _range, _tokens, theChildren)
|
|
221
|
-
quantifier = theChildren[1]
|
|
222
|
-
term = theChildren[0]
|
|
223
|
-
repetition(term, quantifier)
|
|
224
|
-
end
|
|
225
|
-
|
|
226
|
-
# rule('letter_range' => %w[LETTER FROM LETTER_LIT TO LETTER_LIT]).as 'lowercase_from_to'
|
|
202
|
+
# rule('letter_range' => %w[LETTER FROM LETTER_LIT TO LETTER_LIT]).tag 'lowercase_from_to'
|
|
227
203
|
def reduce_lowercase_from_to(_production, _range, _tokens, theChildren)
|
|
228
204
|
raw_range = [theChildren[2].token.lexeme, theChildren[4].token.lexeme]
|
|
229
205
|
range_sorted = raw_range.sort
|
|
@@ -231,7 +207,7 @@ module SrlRuby
|
|
|
231
207
|
char_class(false, ch_range)
|
|
232
208
|
end
|
|
233
209
|
|
|
234
|
-
# rule('letter_range' => %w[UPPERCASE LETTER FROM LETTER_LIT TO LETTER_LIT]).
|
|
210
|
+
# rule('letter_range' => %w[UPPERCASE LETTER FROM LETTER_LIT TO LETTER_LIT]).tag 'uppercase_from_to'
|
|
235
211
|
def reduce_uppercase_from_to(_production, _range, _tokens, theChildren)
|
|
236
212
|
raw_range = [theChildren[3].token.lexeme, theChildren[5].token.lexeme]
|
|
237
213
|
range_sorted = raw_range.sort
|
|
@@ -239,19 +215,19 @@ module SrlRuby
|
|
|
239
215
|
char_class(false, ch_range)
|
|
240
216
|
end
|
|
241
217
|
|
|
242
|
-
# rule('letter_range' => 'LETTER').
|
|
218
|
+
# rule('letter_range' => 'LETTER').tag 'any_lowercase'
|
|
243
219
|
def reduce_any_lowercase(_production, _range, _tokens, _children)
|
|
244
220
|
ch_range = char_range('a', 'z')
|
|
245
221
|
char_class(false, ch_range)
|
|
246
222
|
end
|
|
247
223
|
|
|
248
|
-
# rule('letter_range' => %w[UPPERCASE LETTER]).
|
|
224
|
+
# rule('letter_range' => %w[UPPERCASE LETTER]).tag 'any_uppercase'
|
|
249
225
|
def reduce_any_uppercase(_production, _range, _tokens, _children)
|
|
250
226
|
ch_range = char_range('A', 'Z')
|
|
251
227
|
char_class(false, ch_range)
|
|
252
228
|
end
|
|
253
229
|
|
|
254
|
-
# rule('digit_range' => %w[digit_or_number FROM DIGIT_LIT TO DIGIT_LIT]).
|
|
230
|
+
# rule('digit_range' => %w[digit_or_number FROM DIGIT_LIT TO DIGIT_LIT]).tag 'digits_from_to'
|
|
255
231
|
def reduce_digits_from_to(_production, _range, _tokens, theChildren)
|
|
256
232
|
raw_range = [theChildren[2].token.lexeme, theChildren[4].token.lexeme]
|
|
257
233
|
range_sorted = raw_range.map(&:to_i).sort
|
|
@@ -259,42 +235,42 @@ module SrlRuby
|
|
|
259
235
|
char_class(false, ch_range)
|
|
260
236
|
end
|
|
261
237
|
|
|
262
|
-
# rule('character_class' => %w[ANY CHARACTER]).
|
|
238
|
+
# rule('character_class' => %w[ANY CHARACTER]).tag 'any_character'
|
|
263
239
|
def reduce_any_character(_production, _range, _tokens, _children)
|
|
264
240
|
char_shorthand('w')
|
|
265
241
|
end
|
|
266
242
|
|
|
267
|
-
# rule('character_class' => %w[NO CHARACTER]).
|
|
243
|
+
# rule('character_class' => %w[NO CHARACTER]).tag 'no_character'
|
|
268
244
|
def reduce_no_character(_production, _range, _tokens, _children)
|
|
269
245
|
char_shorthand('W')
|
|
270
246
|
end
|
|
271
247
|
|
|
272
|
-
# rule('character_class' => 'digit_or_number').
|
|
248
|
+
# rule('character_class' => 'digit_or_number').tag 'digit'
|
|
273
249
|
def reduce_digit(_production, _range, _tokens, _children)
|
|
274
250
|
char_shorthand('d')
|
|
275
251
|
end
|
|
276
252
|
|
|
277
|
-
# rule('character_class' => %w[NO DIGIT]).
|
|
253
|
+
# rule('character_class' => %w[NO DIGIT]).tag 'non_digit'
|
|
278
254
|
def reduce_non_digit(_production, _range, _tokens, _children)
|
|
279
255
|
char_shorthand('D')
|
|
280
256
|
end
|
|
281
257
|
|
|
282
|
-
# rule('character_class' => 'WHITESPACE').
|
|
258
|
+
# rule('character_class' => 'WHITESPACE').tag 'whitespace'
|
|
283
259
|
def reduce_whitespace(_production, _range, _tokens, _children)
|
|
284
260
|
char_shorthand('s')
|
|
285
261
|
end
|
|
286
262
|
|
|
287
|
-
# rule('character_class' => %w[NO WHITESPACE]).
|
|
263
|
+
# rule('character_class' => %w[NO WHITESPACE]).tag 'no_whitespace'
|
|
288
264
|
def reduce_no_whitespace(_production, _range, _tokens, _children)
|
|
289
265
|
char_shorthand('S')
|
|
290
266
|
end
|
|
291
267
|
|
|
292
|
-
# rule('character_class' => 'ANYTHING').
|
|
268
|
+
# rule('character_class' => 'ANYTHING').tag 'anything'
|
|
293
269
|
def reduce_anything(_production, _range, _tokens, _children)
|
|
294
270
|
wildcard
|
|
295
271
|
end
|
|
296
272
|
|
|
297
|
-
# rule('character_class' => %w[ONE OF STRING_LIT]).
|
|
273
|
+
# rule('character_class' => %w[ONE OF STRING_LIT]).tag 'one_of'
|
|
298
274
|
def reduce_one_of(_production, _range, _tokens, theChildren)
|
|
299
275
|
raw_literal = theChildren[-1].token.lexeme.dup
|
|
300
276
|
alternatives = raw_literal.chars.map do |ch|
|
|
@@ -310,7 +286,7 @@ module SrlRuby
|
|
|
310
286
|
return Regex::CharClass.new(false, *alternatives)
|
|
311
287
|
end
|
|
312
288
|
|
|
313
|
-
# rule('character_class' => %w[NONE OF STRING_LIT]).
|
|
289
|
+
# rule('character_class' => %w[NONE OF STRING_LIT]).tag 'none_of'
|
|
314
290
|
def reduce_none_of(_production, _range, _tokens, theChildren)
|
|
315
291
|
raw_literal = theChildren[-1].token.lexeme.dup
|
|
316
292
|
chars = raw_literal.chars.map do |ch|
|
|
@@ -319,44 +295,44 @@ module SrlRuby
|
|
|
319
295
|
Regex::CharClass.new(true, *chars)
|
|
320
296
|
end
|
|
321
297
|
|
|
322
|
-
# rule('special_char' => 'TAB').
|
|
298
|
+
# rule('special_char' => 'TAB').tag 'tab'
|
|
323
299
|
def reduce_tab(_production, _range, _tokens, _children)
|
|
324
300
|
Regex::Character.new('\t')
|
|
325
301
|
end
|
|
326
302
|
|
|
327
|
-
# rule('special_char' => ' VERTICAL TAB').
|
|
303
|
+
# rule('special_char' => ' VERTICAL TAB').tag 'vtab'
|
|
328
304
|
def reduce_vtab(_production, _range, _tokens, _children)
|
|
329
305
|
Regex::Character.new('\v')
|
|
330
306
|
end
|
|
331
307
|
|
|
332
|
-
# rule('special_char' => 'BACKSLASH').
|
|
308
|
+
# rule('special_char' => 'BACKSLASH').tag 'backslash'
|
|
333
309
|
def reduce_backslash(_production, _range, _tokens, _children)
|
|
334
310
|
# Double the backslash (because of escaping)
|
|
335
311
|
string_literal('\\', true)
|
|
336
312
|
end
|
|
337
313
|
|
|
338
|
-
# rule('special_char' => %w[NEW LINE]).
|
|
314
|
+
# rule('special_char' => %w[NEW LINE]).tag 'new_line'
|
|
339
315
|
def reduce_new_line(_production, _range, _tokens, _children)
|
|
340
316
|
# TODO: control portability
|
|
341
317
|
Regex::Character.new('\n')
|
|
342
318
|
end
|
|
343
319
|
|
|
344
|
-
# rule('special_char' => %w[CARRIAGE RETURN]).
|
|
320
|
+
# rule('special_char' => %w[CARRIAGE RETURN]).tag 'carriage_return'
|
|
345
321
|
def reduce_carriage_return(_production, _range, _tokens, _children)
|
|
346
322
|
Regex::Character.new('\r')
|
|
347
323
|
end
|
|
348
324
|
|
|
349
|
-
# rule('special_char' => %w[WORD]).
|
|
325
|
+
# rule('special_char' => %w[WORD]).tag 'word'
|
|
350
326
|
def reduce_word(_production, _range, _tokens, _children)
|
|
351
327
|
Regex::Anchor.new('\b')
|
|
352
328
|
end
|
|
353
329
|
|
|
354
|
-
# rule('special_char' => %w[NO WORD]).
|
|
330
|
+
# rule('special_char' => %w[NO WORD]).tag 'no word'
|
|
355
331
|
def reduce_no_word(_production, _range, _tokens, _children)
|
|
356
332
|
Regex::Anchor.new('\B')
|
|
357
333
|
end
|
|
358
334
|
|
|
359
|
-
# rule('literal' => %w[LITERALLY STRING_LIT]).
|
|
335
|
+
# rule('literal' => %w[LITERALLY STRING_LIT]).tag 'literally'
|
|
360
336
|
def reduce_literally(_production, _range, _tokens, theChildren)
|
|
361
337
|
# What if literal is empty?...
|
|
362
338
|
|
|
@@ -364,13 +340,13 @@ module SrlRuby
|
|
|
364
340
|
return string_literal(raw_literal)
|
|
365
341
|
end
|
|
366
342
|
|
|
367
|
-
# rule('raw' => %w[RAW STRING_LIT]).
|
|
343
|
+
# rule('raw' => %w[RAW STRING_LIT]).tag 'raw_literal'
|
|
368
344
|
def reduce_raw_literal(_production, _range, _tokens, theChildren)
|
|
369
345
|
raw_literal = theChildren[-1].token.lexeme.dup
|
|
370
346
|
return Regex::RawExpression.new(raw_literal)
|
|
371
347
|
end
|
|
372
348
|
|
|
373
|
-
# rule('alternation' => %w[ANY OF LPAREN alternatives RPAREN]).
|
|
349
|
+
# rule('alternation' => %w[ANY OF LPAREN alternatives RPAREN]).tag 'any_of'
|
|
374
350
|
def reduce_any_of(_production, _range, _tokens, theChildren)
|
|
375
351
|
first_alternative = theChildren[3].first
|
|
376
352
|
result = nil
|
|
@@ -385,26 +361,21 @@ module SrlRuby
|
|
|
385
361
|
return result
|
|
386
362
|
end
|
|
387
363
|
|
|
388
|
-
# rule('alternatives' => %w[alternatives separator quantifiable]).
|
|
364
|
+
# rule('alternatives' => %w[alternatives separator quantifiable]).tag 'alternative_list'
|
|
389
365
|
def reduce_alternative_list(_production, _range, _tokens, theChildren)
|
|
390
366
|
return theChildren[0] << theChildren[-1]
|
|
391
367
|
end
|
|
392
368
|
|
|
393
|
-
# rule('alternatives' => 'quantifiable').
|
|
369
|
+
# rule('alternatives' => 'quantifiable').tag 'simple_alternative'
|
|
394
370
|
def reduce_simple_alternative(_production, _range, _tokens, theChildren)
|
|
395
371
|
[theChildren.last]
|
|
396
372
|
end
|
|
397
373
|
|
|
398
|
-
# rule('grouping' => %w[LPAREN pattern RPAREN]).
|
|
374
|
+
# rule('grouping' => %w[LPAREN pattern RPAREN]).tag 'grouping_parenthenses'
|
|
399
375
|
def reduce_grouping_parenthenses(_production, _range, _tokens, theChildren)
|
|
400
376
|
Regex::NonCapturingGroup.new(theChildren[1])
|
|
401
377
|
end
|
|
402
378
|
|
|
403
|
-
# rule('capturing_group' => %w[CAPTURE assertable]).as 'capture'
|
|
404
|
-
def reduce_capture(_production, _range, _tokens, theChildren)
|
|
405
|
-
Regex::CapturingGroup.new(theChildren[1])
|
|
406
|
-
end
|
|
407
|
-
|
|
408
379
|
# If the rightmost (sub)expression is a repetition, then make it lazy
|
|
409
380
|
def make_last_repetition_lazy(anExpr)
|
|
410
381
|
sub_expr = anExpr
|
|
@@ -424,51 +395,49 @@ module SrlRuby
|
|
|
424
395
|
end
|
|
425
396
|
end
|
|
426
397
|
|
|
427
|
-
# rule('capturing_group' =>
|
|
428
|
-
#
|
|
429
|
-
def
|
|
398
|
+
# rule('capturing_group' => 'CAPTURE assertable (UNTIL assertable)?').tag
|
|
399
|
+
# 'capture'
|
|
400
|
+
def reduce_capture(_production, _range, _tokens, theChildren)
|
|
401
|
+
return Regex::CapturingGroup.new(theChildren[1]) unless theChildren[2]
|
|
402
|
+
|
|
430
403
|
# Until semantic requires that the last pattern in capture to be lazy
|
|
431
404
|
make_last_repetition_lazy(theChildren[1])
|
|
432
405
|
|
|
433
406
|
group = Regex::CapturingGroup.new(theChildren[1])
|
|
434
|
-
|
|
407
|
+
(_, until_expr) = theChildren[2]
|
|
408
|
+
Regex::Concatenation.new(group, until_expr)
|
|
435
409
|
end
|
|
436
410
|
|
|
437
|
-
# rule('capturing_group' =>
|
|
438
|
-
#
|
|
411
|
+
# rule('capturing_group' => 'CAPTURE assertable AS var_name (UNTIL assertable)?').tag
|
|
412
|
+
# 'named_capture'
|
|
439
413
|
def reduce_named_capture(_production, _range, _tokens, theChildren)
|
|
440
414
|
name = theChildren[3].token.lexeme.dup
|
|
441
|
-
return Regex::CapturingGroup.new(theChildren[1], name)
|
|
442
|
-
end
|
|
415
|
+
return Regex::CapturingGroup.new(theChildren[1], name) unless theChildren[4]
|
|
443
416
|
|
|
444
|
-
# rule('capturing_group' => %w[CAPTURE assertable AS var_name
|
|
445
|
-
# UNTIL assertable]).as 'named_capture_until'
|
|
446
|
-
def reduce_named_capture_until(_production, _range, _tokens, theChildren)
|
|
447
417
|
# Until semantic requires that the last pattern in capture to be lazy
|
|
448
418
|
make_last_repetition_lazy(theChildren[1])
|
|
449
|
-
|
|
450
|
-
name = theChildren[3].token.lexeme.dup
|
|
451
419
|
group = Regex::CapturingGroup.new(theChildren[1], name)
|
|
452
|
-
|
|
420
|
+
(_, until_expr) = theChildren[4]
|
|
421
|
+
return Regex::Concatenation.new(group, until_expr)
|
|
453
422
|
end
|
|
454
423
|
|
|
455
|
-
# rule('quantifier' => 'ONCE').
|
|
424
|
+
# rule('quantifier' => 'ONCE').tag 'once'
|
|
456
425
|
def reduce_once(_production, _range, _tokens, _children)
|
|
457
426
|
multiplicity(1, 1)
|
|
458
427
|
end
|
|
459
428
|
|
|
460
|
-
# rule('quantifier' => 'TWICE').
|
|
429
|
+
# rule('quantifier' => 'TWICE').tag 'twice'
|
|
461
430
|
def reduce_twice(_production, _range, _tokens, _children)
|
|
462
431
|
multiplicity(2, 2)
|
|
463
432
|
end
|
|
464
433
|
|
|
465
|
-
# rule('quantifier' => %w[EXACTLY count TIMES]).
|
|
434
|
+
# rule('quantifier' => %w[EXACTLY count TIMES]).tag 'exactly'
|
|
466
435
|
def reduce_exactly(_production, _range, _tokens, theChildren)
|
|
467
436
|
count = theChildren[1].token.lexeme.to_i
|
|
468
437
|
multiplicity(count, count)
|
|
469
438
|
end
|
|
470
439
|
|
|
471
|
-
# rule('quantifier' =>
|
|
440
|
+
# rule('quantifier' => 'BETWEEN count AND count times_suffix').tag
|
|
472
441
|
# 'between_and'
|
|
473
442
|
def reduce_between_and(_production, _range, _tokens, theChildren)
|
|
474
443
|
lower = theChildren[1].token.lexeme.to_i
|
|
@@ -476,36 +445,26 @@ module SrlRuby
|
|
|
476
445
|
multiplicity(lower, upper)
|
|
477
446
|
end
|
|
478
447
|
|
|
479
|
-
# rule('quantifier' => 'OPTIONAL').
|
|
448
|
+
# rule('quantifier' => 'OPTIONAL').tag 'optional'
|
|
480
449
|
def reduce_optional(_production, _range, _tokens, _children)
|
|
481
450
|
multiplicity(0, 1)
|
|
482
451
|
end
|
|
483
452
|
|
|
484
|
-
# rule('quantifier' => %w[ONCE OR MORE]).
|
|
453
|
+
# rule('quantifier' => %w[ONCE OR MORE]).tag 'once_or_more'
|
|
485
454
|
def reduce_once_or_more(_production, _range, _tokens, _children)
|
|
486
455
|
multiplicity(1, :more)
|
|
487
456
|
end
|
|
488
457
|
|
|
489
|
-
# rule('quantifier' => %w[NEVER OR MORE]).
|
|
458
|
+
# rule('quantifier' => %w[NEVER OR MORE]).tag 'never_or_more'
|
|
490
459
|
def reduce_never_or_more(_production, _range, _tokens, _children)
|
|
491
460
|
multiplicity(0, :more)
|
|
492
461
|
end
|
|
493
462
|
|
|
494
|
-
# rule('quantifier' => %w[AT LEAST count TIMES]).
|
|
463
|
+
# rule('quantifier' => %w[AT LEAST count TIMES]).tag 'at_least'
|
|
495
464
|
def reduce_at_least(_production, _range, _tokens, theChildren)
|
|
496
465
|
count = theChildren[2].token.lexeme.to_i
|
|
497
466
|
multiplicity(count, :more)
|
|
498
467
|
end
|
|
499
|
-
|
|
500
|
-
# rule('times_suffix' => 'TIMES').as 'times_keyword'
|
|
501
|
-
def reduce_times_keyword(_production, _range, _tokens, _children)
|
|
502
|
-
nil
|
|
503
|
-
end
|
|
504
|
-
|
|
505
|
-
# rule('times_suffix' => []).as 'times_dropped'
|
|
506
|
-
def reduce_times_dropped(_production, _range, _tokens, _children)
|
|
507
|
-
nil
|
|
508
|
-
end
|
|
509
468
|
end # class
|
|
510
469
|
end # module
|
|
511
470
|
# End of file
|