srl_ruby 0.4.7 → 0.4.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c0ad4df7433bb3c5e88e03e5670c306d1a70b6ec43f831c3d6d376e1776856e5
4
- data.tar.gz: 57d9791c96e46524e08d21606d17d4757bea2d9d9cd4e1322276733e5cf1642c
3
+ metadata.gz: 4142454106f1b3b0a0e1e9b7c382ba6c5088f34a7b4d2e4c9437164537bb766a
4
+ data.tar.gz: 2ded972212dc2db8b037aba56aec6f79917a90a945f56c8f9f72b1bd88cd8b69
5
5
  SHA512:
6
- metadata.gz: 151d3cdfd98bc907c2c4c3b63e317852fec743dc12b27f509b32285a8bd100242cc745c422a3c81641f4152453d3acc713246d8b907b532f635db5f99e83d2f2
7
- data.tar.gz: 00b946261c11af9e9b64b460664a33498d1cd57685f3a6fc884c238c67c163b1c7a26efce508c3a9bd6e830bae82c1420697923e8889783b432c00333fffb2c7
6
+ metadata.gz: d7da9074cd772c28dc7eeaa8072d39fb5a91a08dba1665982fbf08303582c84742cf72ca6785ed18f1944cb11fcfd25fb011a37f93055c552011543235799669
7
+ data.tar.gz: '070724971995e366a27232732d5accf62c3e2141807ae80a7548d0ae98a28004bf811c50119001e581648c3e262cba7295ee6117bab5f1bddea3110e692d9c94'
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## [0.4.8] - 2021-08-27
2
+ - Updated dependencies (Bundler >~ 2.2), (Rley >~ 0.8.03)
3
+ - Grammar refactoring to take profit of new Rley rule syntax.
4
+
5
+ ### Changed
6
+ - File `srl_ruby.gemspec` Updated the dependencies
7
+ - File `grammar.rb` Grammar refactored (use ? * + modifiers in production rules)
8
+ - class `ASTBuilder` updated `reduce_` to reflect new refactored production rules.
9
+
1
10
  ## [0.4.7] - 2021-08-24
2
11
  - Updated dependencies (Ruby >= 2.5), (Rley >= 0.8.02)
3
12
  - Code restyling to please rubocop 1.19.1.
data/LICENSE.txt CHANGED
@@ -5,7 +5,7 @@ the 'srl_test' directory, which is subject to its own license.
5
5
 
6
6
  The MIT License (MIT)
7
7
 
8
- Copyright (c) 2018-2019 Dimitri Geshef
8
+ Copyright (c) 2018-2021 Dimitri Geshef
9
9
 
10
10
  Permission is hereby granted, free of charge, to any person obtaining a copy
11
11
  of this software and associated documentation files (the "Software"), to deal
@@ -118,70 +118,52 @@ module SrlRuby
118
118
  Regex::Anchor.new('^')
119
119
  end
120
120
 
121
- # rule('expression' => %w[pattern flags]).as 'flagged_expr'
121
+ # rule('expression' => 'pattern (flags)?').tag 'flagged_expr'
122
122
  def reduce_flagged_expr(_production, aRange, theTokens, theChildren)
123
123
  @options = theChildren[1] if theChildren[1]
124
124
  return_first_child(aRange, theTokens, theChildren)
125
125
  end
126
126
 
127
- # rule('pattern' => %w[pattern separator sub_pattern]).as 'pattern_sequence'
127
+ # rule('pattern' => 'subpattern (separator sub_pattern)*').tag 'pattern_sequence'
128
128
  def reduce_pattern_sequence(_production, _range, _tokens, theChildren)
129
- third_member = theChildren[2]
130
- if third_member.kind_of?(Regex::Lookaround) && third_member.dir == :behind
131
- Regex::Concatenation.new(theChildren[2], theChildren[0])
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)
132
134
  else
133
- Regex::Concatenation.new(theChildren[0], theChildren[2])
135
+ Regex::Concatenation.new(theChildren[0], *successors)
134
136
  end
135
137
  end
136
138
 
137
- # rule('pattern' => 'sub_pattern').as 'basic_pattern'
138
- def reduce_basic_pattern(_production, aRange, theTokens, theChildren)
139
- return_first_child(aRange, theTokens, theChildren)
140
- end
141
-
142
- # rule('sub_pattern' => 'assertion').as 'assertion_sub_pattern'
139
+ # rule('sub_pattern' => 'assertion').tag 'assertion_sub_pattern'
143
140
  def reduce_assertion_sub_pattern(_production, aRange, theTokens, theChildren)
144
141
  return_first_child(aRange, theTokens, theChildren)
145
142
  end
146
143
 
147
- # rule('flags' => %[flags separator single_flag]).as 'flag_sequence'
144
+ # rule('flags' => '(separator single_flag)+').tag 'flag_sequence'
148
145
  def reduce_flag_sequence(_production, _range, _tokens, theChildren)
149
- theChildren[0] << theChildren[2]
150
- end
151
-
152
- # rule('flags' => %w[separator single_flag]).as 'flag_simple'
153
- def reduce_flag_simple(_production, _range, _tokens, theChildren)
154
- [theChildren.last]
146
+ theChildren[0].map { |(_, flag)| flag }
155
147
  end
156
148
 
157
- # rule('single_flag' => %w[CASE INSENSITIVE]).as 'case_insensitive'
149
+ # rule('single_flag' => %w[CASE INSENSITIVE]).tag 'case_insensitive'
158
150
  def reduce_case_insensitive(_production, _range, _tokens, _children)
159
151
  Regexp::IGNORECASE
160
152
  end
161
153
 
162
- # rule('single_flag' => %w[MULTI LINE]).as 'multi_line'
154
+ # rule('single_flag' => %w[MULTI LINE]).tag 'multi_line'
163
155
  def reduce_multi_line(_production, _range, _tokens, _children)
164
156
  Regexp::MULTILINE
165
157
  end
166
158
 
167
- # rule('single_flag' => %w[ALL LAZY]).as 'all_lazy'
159
+ # rule('single_flag' => %w[ALL LAZY]).tag 'all_lazy'
168
160
  def reduce_all_lazy(_production, _range, _tokens, _children)
169
161
  :ALL_LAZY
170
162
  end
171
163
 
172
- # rule 'quantifiable' => %w[begin_anchor anchorable end_anchor]
173
- def reduce_pinned_quantifiable(_production, _range, _tokens, theChildren)
174
- Regex::Concatenation.new(*theChildren)
175
- end
176
-
177
- # rule 'quantifiable' => %w[begin_anchor anchorable]
178
- def reduce_begin_anchor_quantifiable(_production, _range, _tokens, theChildren)
179
- Regex::Concatenation.new(*theChildren)
180
- end
181
-
182
- # rule 'quantifiable' => %w[anchorable end_anchor]
183
- def reduce_end_anchor_quantifiable(_production, _range, _tokens, theChildren)
184
- 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.compact)
185
167
  end
186
168
 
187
169
  # rule 'begin_anchor' => %w[STARTS WITH]
@@ -194,39 +176,30 @@ module SrlRuby
194
176
  begin_anchor
195
177
  end
196
178
 
197
- # rule('end_anchor' => %w[separator MUST END]).as 'end_anchor'
179
+ # rule('end_anchor' => %w[separator MUST END]).tag 'end_anchor'
198
180
  def reduce_end_anchor(_production, _range, _tokens, _children)
199
181
  Regex::Anchor.new('$')
200
182
  end
201
183
 
202
- # rule('assertion' => %w[IF FOLLOWED BY assertable]).as 'if_followed'
184
+ # rule('assertion' => 'IF NOT? FOLLOWED BY assertable')
203
185
  def reduce_if_followed(_production, _range, _tokens, theChildren)
204
- Regex::Lookaround.new(theChildren.last, :ahead, :positive)
186
+ polarity = theChildren[1] ? :negative : :positive
187
+ Regex::Lookaround.new(theChildren.last, :ahead, polarity)
205
188
  end
206
189
 
207
- # rule('assertion' => %w[IF NOT FOLLOWED BY assertable]).as 'if_not_followed'
208
- def reduce_if_not_followed(_production, _range, _tokens, theChildren)
209
- Regex::Lookaround.new(theChildren.last, :ahead, :negative)
210
- end
211
-
212
- # rule('assertion' => %w[IF ALREADY HAD assertable]).as 'if_had'
190
+ # rule('assertion' => 'IF NOT? ALREADY HAD assertable')
213
191
  def reduce_if_had(_production, _range, _tokens, theChildren)
214
- Regex::Lookaround.new(theChildren.last, :behind, :positive)
192
+ polarity = theChildren[1] ? :negative : :positive
193
+ Regex::Lookaround.new(theChildren.last, :behind, polarity)
215
194
  end
216
195
 
217
- # rule('assertion' => %w[IF NOT ALREADY HAD assertable]).as 'if_not_had'
218
- def reduce_if_not_had(_production, _range, _tokens, theChildren)
219
- Regex::Lookaround.new(theChildren.last, :behind, :negative)
196
+ # rule('assertable' => 'term quantifier?').tag 'assertable'
197
+ def reduce_assertable(_production, _range, _tokens, theChildren)
198
+ (term, quantifier) = theChildren
199
+ quantifier ? repetition(term, quantifier) : term
220
200
  end
221
201
 
222
- # rule('assertable' => %w[term quantifier]).as 'quantified_assertable'
223
- def reduce_quantified_assertable(_production, _range, _tokens, theChildren)
224
- quantifier = theChildren[1]
225
- term = theChildren[0]
226
- repetition(term, quantifier)
227
- end
228
-
229
- # 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'
230
203
  def reduce_lowercase_from_to(_production, _range, _tokens, theChildren)
231
204
  raw_range = [theChildren[2].token.lexeme, theChildren[4].token.lexeme]
232
205
  range_sorted = raw_range.sort
@@ -234,7 +207,7 @@ module SrlRuby
234
207
  char_class(false, ch_range)
235
208
  end
236
209
 
237
- # rule('letter_range' => %w[UPPERCASE LETTER FROM LETTER_LIT TO LETTER_LIT]).as 'uppercase_from_to'
210
+ # rule('letter_range' => %w[UPPERCASE LETTER FROM LETTER_LIT TO LETTER_LIT]).tag 'uppercase_from_to'
238
211
  def reduce_uppercase_from_to(_production, _range, _tokens, theChildren)
239
212
  raw_range = [theChildren[3].token.lexeme, theChildren[5].token.lexeme]
240
213
  range_sorted = raw_range.sort
@@ -242,19 +215,19 @@ module SrlRuby
242
215
  char_class(false, ch_range)
243
216
  end
244
217
 
245
- # rule('letter_range' => 'LETTER').as 'any_lowercase'
218
+ # rule('letter_range' => 'LETTER').tag 'any_lowercase'
246
219
  def reduce_any_lowercase(_production, _range, _tokens, _children)
247
220
  ch_range = char_range('a', 'z')
248
221
  char_class(false, ch_range)
249
222
  end
250
223
 
251
- # rule('letter_range' => %w[UPPERCASE LETTER]).as 'any_uppercase'
224
+ # rule('letter_range' => %w[UPPERCASE LETTER]).tag 'any_uppercase'
252
225
  def reduce_any_uppercase(_production, _range, _tokens, _children)
253
226
  ch_range = char_range('A', 'Z')
254
227
  char_class(false, ch_range)
255
228
  end
256
229
 
257
- # rule('digit_range' => %w[digit_or_number FROM DIGIT_LIT TO DIGIT_LIT]).as 'digits_from_to'
230
+ # rule('digit_range' => %w[digit_or_number FROM DIGIT_LIT TO DIGIT_LIT]).tag 'digits_from_to'
258
231
  def reduce_digits_from_to(_production, _range, _tokens, theChildren)
259
232
  raw_range = [theChildren[2].token.lexeme, theChildren[4].token.lexeme]
260
233
  range_sorted = raw_range.map(&:to_i).sort
@@ -262,42 +235,42 @@ module SrlRuby
262
235
  char_class(false, ch_range)
263
236
  end
264
237
 
265
- # rule('character_class' => %w[ANY CHARACTER]).as 'any_character'
238
+ # rule('character_class' => %w[ANY CHARACTER]).tag 'any_character'
266
239
  def reduce_any_character(_production, _range, _tokens, _children)
267
240
  char_shorthand('w')
268
241
  end
269
242
 
270
- # rule('character_class' => %w[NO CHARACTER]).as 'no_character'
243
+ # rule('character_class' => %w[NO CHARACTER]).tag 'no_character'
271
244
  def reduce_no_character(_production, _range, _tokens, _children)
272
245
  char_shorthand('W')
273
246
  end
274
247
 
275
- # rule('character_class' => 'digit_or_number').as 'digit'
248
+ # rule('character_class' => 'digit_or_number').tag 'digit'
276
249
  def reduce_digit(_production, _range, _tokens, _children)
277
250
  char_shorthand('d')
278
251
  end
279
252
 
280
- # rule('character_class' => %w[NO DIGIT]).as 'non_digit'
253
+ # rule('character_class' => %w[NO DIGIT]).tag 'non_digit'
281
254
  def reduce_non_digit(_production, _range, _tokens, _children)
282
255
  char_shorthand('D')
283
256
  end
284
257
 
285
- # rule('character_class' => 'WHITESPACE').as 'whitespace'
258
+ # rule('character_class' => 'WHITESPACE').tag 'whitespace'
286
259
  def reduce_whitespace(_production, _range, _tokens, _children)
287
260
  char_shorthand('s')
288
261
  end
289
262
 
290
- # rule('character_class' => %w[NO WHITESPACE]).as 'no_whitespace'
263
+ # rule('character_class' => %w[NO WHITESPACE]).tag 'no_whitespace'
291
264
  def reduce_no_whitespace(_production, _range, _tokens, _children)
292
265
  char_shorthand('S')
293
266
  end
294
267
 
295
- # rule('character_class' => 'ANYTHING').as 'anything'
268
+ # rule('character_class' => 'ANYTHING').tag 'anything'
296
269
  def reduce_anything(_production, _range, _tokens, _children)
297
270
  wildcard
298
271
  end
299
272
 
300
- # rule('character_class' => %w[ONE OF STRING_LIT]).as 'one_of'
273
+ # rule('character_class' => %w[ONE OF STRING_LIT]).tag 'one_of'
301
274
  def reduce_one_of(_production, _range, _tokens, theChildren)
302
275
  raw_literal = theChildren[-1].token.lexeme.dup
303
276
  alternatives = raw_literal.chars.map do |ch|
@@ -313,7 +286,7 @@ module SrlRuby
313
286
  return Regex::CharClass.new(false, *alternatives)
314
287
  end
315
288
 
316
- # rule('character_class' => %w[NONE OF STRING_LIT]).as 'none_of'
289
+ # rule('character_class' => %w[NONE OF STRING_LIT]).tag 'none_of'
317
290
  def reduce_none_of(_production, _range, _tokens, theChildren)
318
291
  raw_literal = theChildren[-1].token.lexeme.dup
319
292
  chars = raw_literal.chars.map do |ch|
@@ -322,44 +295,44 @@ module SrlRuby
322
295
  Regex::CharClass.new(true, *chars)
323
296
  end
324
297
 
325
- # rule('special_char' => 'TAB').as 'tab'
298
+ # rule('special_char' => 'TAB').tag 'tab'
326
299
  def reduce_tab(_production, _range, _tokens, _children)
327
300
  Regex::Character.new('\t')
328
301
  end
329
302
 
330
- # rule('special_char' => ' VERTICAL TAB').as 'vtab'
303
+ # rule('special_char' => ' VERTICAL TAB').tag 'vtab'
331
304
  def reduce_vtab(_production, _range, _tokens, _children)
332
305
  Regex::Character.new('\v')
333
306
  end
334
307
 
335
- # rule('special_char' => 'BACKSLASH').as 'backslash'
308
+ # rule('special_char' => 'BACKSLASH').tag 'backslash'
336
309
  def reduce_backslash(_production, _range, _tokens, _children)
337
310
  # Double the backslash (because of escaping)
338
311
  string_literal('\\', true)
339
312
  end
340
313
 
341
- # rule('special_char' => %w[NEW LINE]).as 'new_line'
314
+ # rule('special_char' => %w[NEW LINE]).tag 'new_line'
342
315
  def reduce_new_line(_production, _range, _tokens, _children)
343
316
  # TODO: control portability
344
317
  Regex::Character.new('\n')
345
318
  end
346
319
 
347
- # rule('special_char' => %w[CARRIAGE RETURN]).as 'carriage_return'
320
+ # rule('special_char' => %w[CARRIAGE RETURN]).tag 'carriage_return'
348
321
  def reduce_carriage_return(_production, _range, _tokens, _children)
349
322
  Regex::Character.new('\r')
350
323
  end
351
324
 
352
- # rule('special_char' => %w[WORD]).as 'word'
325
+ # rule('special_char' => %w[WORD]).tag 'word'
353
326
  def reduce_word(_production, _range, _tokens, _children)
354
327
  Regex::Anchor.new('\b')
355
328
  end
356
329
 
357
- # rule('special_char' => %w[NO WORD]).as 'no word'
330
+ # rule('special_char' => %w[NO WORD]).tag 'no word'
358
331
  def reduce_no_word(_production, _range, _tokens, _children)
359
332
  Regex::Anchor.new('\B')
360
333
  end
361
334
 
362
- # rule('literal' => %w[LITERALLY STRING_LIT]).as 'literally'
335
+ # rule('literal' => %w[LITERALLY STRING_LIT]).tag 'literally'
363
336
  def reduce_literally(_production, _range, _tokens, theChildren)
364
337
  # What if literal is empty?...
365
338
 
@@ -367,13 +340,13 @@ module SrlRuby
367
340
  return string_literal(raw_literal)
368
341
  end
369
342
 
370
- # rule('raw' => %w[RAW STRING_LIT]).as 'raw_literal'
343
+ # rule('raw' => %w[RAW STRING_LIT]).tag 'raw_literal'
371
344
  def reduce_raw_literal(_production, _range, _tokens, theChildren)
372
345
  raw_literal = theChildren[-1].token.lexeme.dup
373
346
  return Regex::RawExpression.new(raw_literal)
374
347
  end
375
348
 
376
- # rule('alternation' => %w[ANY OF LPAREN alternatives RPAREN]).as 'any_of'
349
+ # rule('alternation' => %w[ANY OF LPAREN alternatives RPAREN]).tag 'any_of'
377
350
  def reduce_any_of(_production, _range, _tokens, theChildren)
378
351
  first_alternative = theChildren[3].first
379
352
  result = nil
@@ -388,26 +361,21 @@ module SrlRuby
388
361
  return result
389
362
  end
390
363
 
391
- # rule('alternatives' => %w[alternatives separator quantifiable]).as 'alternative_list'
364
+ # rule('alternatives' => %w[alternatives separator quantifiable]).tag 'alternative_list'
392
365
  def reduce_alternative_list(_production, _range, _tokens, theChildren)
393
366
  return theChildren[0] << theChildren[-1]
394
367
  end
395
368
 
396
- # rule('alternatives' => 'quantifiable').as 'simple_alternative'
369
+ # rule('alternatives' => 'quantifiable').tag 'simple_alternative'
397
370
  def reduce_simple_alternative(_production, _range, _tokens, theChildren)
398
371
  [theChildren.last]
399
372
  end
400
373
 
401
- # rule('grouping' => %w[LPAREN pattern RPAREN]).as 'grouping_parenthenses'
374
+ # rule('grouping' => %w[LPAREN pattern RPAREN]).tag 'grouping_parenthenses'
402
375
  def reduce_grouping_parenthenses(_production, _range, _tokens, theChildren)
403
376
  Regex::NonCapturingGroup.new(theChildren[1])
404
377
  end
405
378
 
406
- # rule('capturing_group' => %w[CAPTURE assertable]).as 'capture'
407
- def reduce_capture(_production, _range, _tokens, theChildren)
408
- Regex::CapturingGroup.new(theChildren[1])
409
- end
410
-
411
379
  # If the rightmost (sub)expression is a repetition, then make it lazy
412
380
  def make_last_repetition_lazy(anExpr)
413
381
  sub_expr = anExpr
@@ -427,51 +395,49 @@ module SrlRuby
427
395
  end
428
396
  end
429
397
 
430
- # rule('capturing_group' => %w[CAPTURE assertable UNTIL assertable]).as
431
- # 'capture_until'
432
- def reduce_capture_until(_production, _range, _tokens, theChildren)
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
+
433
403
  # Until semantic requires that the last pattern in capture to be lazy
434
404
  make_last_repetition_lazy(theChildren[1])
435
405
 
436
406
  group = Regex::CapturingGroup.new(theChildren[1])
437
- return Regex::Concatenation.new(group, theChildren[3])
407
+ (_, until_expr) = theChildren[2]
408
+ Regex::Concatenation.new(group, until_expr)
438
409
  end
439
410
 
440
- # rule('capturing_group' => %w[CAPTURE assertable AS var_name]).as
441
- # 'named_capture'
411
+ # rule('capturing_group' => 'CAPTURE assertable AS var_name (UNTIL assertable)?').tag
412
+ # 'named_capture'
442
413
  def reduce_named_capture(_production, _range, _tokens, theChildren)
443
414
  name = theChildren[3].token.lexeme.dup
444
- return Regex::CapturingGroup.new(theChildren[1], name)
445
- end
415
+ return Regex::CapturingGroup.new(theChildren[1], name) unless theChildren[4]
446
416
 
447
- # rule('capturing_group' => %w[CAPTURE assertable AS var_name
448
- # UNTIL assertable]).as 'named_capture_until'
449
- def reduce_named_capture_until(_production, _range, _tokens, theChildren)
450
417
  # Until semantic requires that the last pattern in capture to be lazy
451
418
  make_last_repetition_lazy(theChildren[1])
452
-
453
- name = theChildren[3].token.lexeme.dup
454
419
  group = Regex::CapturingGroup.new(theChildren[1], name)
455
- return Regex::Concatenation.new(group, theChildren[5])
420
+ (_, until_expr) = theChildren[4]
421
+ return Regex::Concatenation.new(group, until_expr)
456
422
  end
457
423
 
458
- # rule('quantifier' => 'ONCE').as 'once'
424
+ # rule('quantifier' => 'ONCE').tag 'once'
459
425
  def reduce_once(_production, _range, _tokens, _children)
460
426
  multiplicity(1, 1)
461
427
  end
462
428
 
463
- # rule('quantifier' => 'TWICE').as 'twice'
429
+ # rule('quantifier' => 'TWICE').tag 'twice'
464
430
  def reduce_twice(_production, _range, _tokens, _children)
465
431
  multiplicity(2, 2)
466
432
  end
467
433
 
468
- # rule('quantifier' => %w[EXACTLY count TIMES]).as 'exactly'
434
+ # rule('quantifier' => %w[EXACTLY count TIMES]).tag 'exactly'
469
435
  def reduce_exactly(_production, _range, _tokens, theChildren)
470
436
  count = theChildren[1].token.lexeme.to_i
471
437
  multiplicity(count, count)
472
438
  end
473
439
 
474
- # rule('quantifier' => %w[BETWEEN count AND count times_suffix]).as
440
+ # rule('quantifier' => 'BETWEEN count AND count times_suffix').tag
475
441
  # 'between_and'
476
442
  def reduce_between_and(_production, _range, _tokens, theChildren)
477
443
  lower = theChildren[1].token.lexeme.to_i
@@ -479,36 +445,26 @@ module SrlRuby
479
445
  multiplicity(lower, upper)
480
446
  end
481
447
 
482
- # rule('quantifier' => 'OPTIONAL').as 'optional'
448
+ # rule('quantifier' => 'OPTIONAL').tag 'optional'
483
449
  def reduce_optional(_production, _range, _tokens, _children)
484
450
  multiplicity(0, 1)
485
451
  end
486
452
 
487
- # rule('quantifier' => %w[ONCE OR MORE]).as 'once_or_more'
453
+ # rule('quantifier' => %w[ONCE OR MORE]).tag 'once_or_more'
488
454
  def reduce_once_or_more(_production, _range, _tokens, _children)
489
455
  multiplicity(1, :more)
490
456
  end
491
457
 
492
- # rule('quantifier' => %w[NEVER OR MORE]).as 'never_or_more'
458
+ # rule('quantifier' => %w[NEVER OR MORE]).tag 'never_or_more'
493
459
  def reduce_never_or_more(_production, _range, _tokens, _children)
494
460
  multiplicity(0, :more)
495
461
  end
496
462
 
497
- # rule('quantifier' => %w[AT LEAST count TIMES]).as 'at_least'
463
+ # rule('quantifier' => %w[AT LEAST count TIMES]).tag 'at_least'
498
464
  def reduce_at_least(_production, _range, _tokens, theChildren)
499
465
  count = theChildren[2].token.lexeme.to_i
500
466
  multiplicity(count, :more)
501
467
  end
502
-
503
- # rule('times_suffix' => 'TIMES').as 'times_keyword'
504
- def reduce_times_keyword(_production, _range, _tokens, _children)
505
- nil
506
- end
507
-
508
- # rule('times_suffix' => []).as 'times_dropped'
509
- def reduce_times_dropped(_production, _range, _tokens, _children)
510
- nil
511
- end
512
468
  end # class
513
469
  end # module
514
470
  # End of file
@@ -31,97 +31,83 @@ module SrlRuby
31
31
  add_terminals('LAZY')
32
32
 
33
33
  # Grammar rules...
34
- rule('srl' => 'expression').as 'start_rule'
35
- rule('expression' => 'pattern flags').as 'flagged_expr'
36
- rule('expression' => 'pattern').as 'simple_expr'
37
- rule('pattern' => 'pattern separator sub_pattern').as 'pattern_sequence'
38
- rule('pattern' => 'sub_pattern').as 'basic_pattern'
39
- rule('sub_pattern' => 'quantifiable').as 'quantifiable_sub_pattern'
40
- rule('sub_pattern' => 'assertion').as 'assertion_sub_pattern'
41
- rule('separator' => 'COMMA').as 'comma_separator'
42
- rule('separator' => []).as 'void_separator'
43
- rule('flags' => 'flags separator single_flag').as 'flag_sequence'
44
- rule('flags' => 'separator single_flag').as 'flag_simple'
45
- rule('single_flag' => 'CASE INSENSITIVE').as 'case_insensitive'
46
- rule('single_flag' => 'MULTI LINE').as 'multi_line'
47
- rule('single_flag' => 'ALL LAZY').as 'all_lazy'
48
- rule('quantifiable' => 'begin_anchor anchorable end_anchor').as 'pinned_quantifiable'
49
- rule('quantifiable' => 'begin_anchor anchorable').as 'begin_anchor_quantifiable'
50
- rule('quantifiable' => 'anchorable end_anchor').as 'end_anchor_quantifiable'
51
- rule('quantifiable' => 'anchorable').as 'simple_quantifiable'
52
- rule('begin_anchor' => 'STARTS WITH').as 'starts_with'
53
- rule('begin_anchor' => 'BEGIN WITH').as 'begin_with'
54
- rule('end_anchor' => 'separator MUST END').as 'end_anchor'
55
- rule('anchorable' => 'assertable').as 'simple_anchorable'
56
- rule('assertion' => 'IF FOLLOWED BY assertable').as 'if_followed'
57
- rule('assertion' => 'IF NOT FOLLOWED BY assertable').as 'if_not_followed'
58
- rule('assertion' => 'IF ALREADY HAD assertable').as 'if_had'
59
- rule('assertion' => 'IF NOT ALREADY HAD assertable').as 'if_not_had'
60
- rule('assertable' => 'term').as 'simple_assertable'
61
- rule('assertable' => 'term quantifier').as 'quantified_assertable'
62
- rule('term' => 'atom').as 'atom_term'
63
- rule('term' => 'alternation').as 'alternation_term'
64
- rule('term' => 'grouping').as 'grouping_term'
65
- rule('term' => 'capturing_group').as 'capturing_group_atom'
66
- rule('atom' => 'letter_range').as 'letter_range_atom'
67
- rule('atom' => 'digit_range').as 'digit_range_atom'
68
- rule('atom' => 'character_class').as 'character_class_atom'
69
- rule('atom' => 'special_char').as 'special_char_atom'
70
- rule('atom' => 'literal').as 'literal_atom'
71
- rule('atom' => 'raw').as 'raw_atom'
72
- rule('letter_range' => 'LETTER FROM LETTER_LIT TO LETTER_LIT').as 'lowercase_from_to'
73
- rule('letter_range' => 'UPPERCASE LETTER FROM LETTER_LIT TO LETTER_LIT').as 'uppercase_from_to'
74
- rule('letter_range' => 'LETTER').as 'any_lowercase'
75
- rule('letter_range' => 'UPPERCASE LETTER').as 'any_uppercase'
76
- rule('digit_range' => 'digit_or_number FROM DIGIT_LIT TO DIGIT_LIT').as 'digits_from_to'
77
- rule('character_class' => 'ANY CHARACTER').as 'any_character'
78
- rule('character_class' => 'NO CHARACTER').as 'no_character'
79
- rule('character_class' => 'digit_or_number').as 'digit'
80
- rule('character_class' => 'NO DIGIT').as 'non_digit'
81
- rule('character_class' => 'WHITESPACE').as 'whitespace'
82
- rule('character_class' => 'NO WHITESPACE').as 'no_whitespace'
83
- rule('character_class' => 'ANYTHING').as 'anything'
84
- rule('character_class' => 'ONE OF cclass').as 'one_of'
85
- rule('character_class' => 'NONE OF cclass').as 'none_of'
86
- rule('cclass' => 'STRING_LIT').as 'quoted_cclass' # Preferred syntax
87
- rule('cclass' => 'INTEGER').as 'digits_cclass'
88
- rule('cclass' => 'IDENTIFIER').as 'identifier_cclass'
89
- rule('cclass' => 'CHAR_CLASS').as 'unquoted_cclass'
90
- rule('special_char' => 'TAB').as 'tab'
91
- rule('special_char' => 'VERTICAL TAB').as 'vtab'
92
- rule('special_char' => 'BACKSLASH').as 'backslash'
93
- rule('special_char' => 'NEW LINE').as 'new_line'
94
- rule('special_char' => 'CARRIAGE RETURN').as 'carriage_return'
95
- rule('special_char' => 'WORD').as 'word'
96
- rule('special_char' => 'NO WORD').as 'no_word'
97
- rule('literal' => 'LITERALLY STRING_LIT').as 'literally'
98
- rule('raw' => 'RAW STRING_LIT').as 'raw_literal'
99
- rule('alternation' => 'any_or_either OF LPAREN alternatives RPAREN').as 'any_of'
100
- rule('alternatives' => 'alternatives separator quantifiable').as 'alternative_list'
101
- rule('alternatives' => 'quantifiable').as 'simple_alternative'
102
- rule('any_or_either' => 'ANY').as 'any_keyword'
103
- rule('any_or_either' => 'EITHER').as 'either_keyword'
104
- rule('grouping' => 'LPAREN pattern RPAREN').as 'grouping_parenthenses'
105
- rule('capturing_group' => 'CAPTURE assertable').as 'capture'
106
- rule('capturing_group' => 'CAPTURE assertable UNTIL assertable').as 'capture_until'
107
- rule('capturing_group' => 'CAPTURE assertable AS var_name').as 'named_capture'
108
- rule('capturing_group' => 'CAPTURE assertable AS var_name UNTIL assertable').as 'named_capture_until'
109
- rule('var_name' => 'STRING_LIT').as 'var_name'
110
- rule('var_name' => 'IDENTIFIER').as 'var_ident' # capture name not enclosed between quotes
111
- rule('quantifier' => 'ONCE').as 'once'
112
- rule('quantifier' => 'TWICE').as 'twice'
113
- rule('quantifier' => 'EXACTLY count TIMES').as 'exactly'
114
- rule('quantifier' => 'BETWEEN count AND count times_suffix').as 'between_and'
115
- rule('quantifier' => 'OPTIONAL').as 'optional'
116
- rule('quantifier' => 'ONCE OR MORE').as 'once_or_more'
117
- rule('quantifier' => 'NEVER OR MORE').as 'never_or_more'
118
- rule('quantifier' => 'AT LEAST count TIMES').as 'at_least'
119
- rule('digit_or_number' => 'DIGIT').as 'digit_keyword'
120
- rule('digit_or_number' => 'NUMBER').as 'number_keyword'
121
- rule('count' => 'DIGIT_LIT').as 'single_digit'
122
- rule('count' => 'INTEGER').as 'integer_count'
123
- rule('times_suffix' => 'TIMES').as 'times_keyword'
124
- rule('times_suffix' => []).as 'times_dropped'
34
+ rule('srl' => 'expression').tag 'start_rule'
35
+ rule('expression' => 'pattern flags?').tag 'flagged_expr'
36
+ rule('pattern' => 'sub_pattern (separator sub_pattern)*').tag 'pattern_sequence'
37
+ rule('sub_pattern' => 'quantifiable').tag 'quantifiable_sub_pattern'
38
+ rule('sub_pattern' => 'assertion').tag 'assertion_sub_pattern'
39
+ rule('separator' => 'COMMA?')
40
+ rule('flags' => '(separator single_flag)+').tag 'flag_sequence'
41
+ rule('single_flag' => 'CASE INSENSITIVE').tag 'case_insensitive'
42
+ rule('single_flag' => 'MULTI LINE').tag 'multi_line'
43
+ rule('single_flag' => 'ALL LAZY').tag 'all_lazy'
44
+ rule('quantifiable' => 'begin_anchor? anchorable end_anchor?').tag 'quantifiable'
45
+ rule('begin_anchor' => 'STARTS WITH').tag 'starts_with'
46
+ rule('begin_anchor' => 'BEGIN WITH').tag 'begin_with'
47
+ rule('end_anchor' => 'separator MUST END').tag 'end_anchor'
48
+ rule('anchorable' => 'assertable').tag 'simple_anchorable'
49
+ rule('assertion' => 'IF NOT? FOLLOWED BY assertable').tag 'if_followed'
50
+ rule('assertion' => 'IF NOT? ALREADY HAD assertable').tag 'if_had'
51
+ rule('assertable' => 'term quantifier?').tag 'assertable'
52
+ rule('term' => 'atom').tag 'atom_term'
53
+ rule('term' => 'alternation').tag 'alternation_term'
54
+ rule('term' => 'grouping').tag 'grouping_term'
55
+ rule('term' => 'capturing_group').tag 'capturing_group_atom'
56
+ rule('atom' => 'letter_range').tag 'letter_range_atom'
57
+ rule('atom' => 'digit_range').tag 'digit_range_atom'
58
+ rule('atom' => 'character_class').tag 'character_class_atom'
59
+ rule('atom' => 'special_char').tag 'special_char_atom'
60
+ rule('atom' => 'literal').tag 'literal_atom'
61
+ rule('atom' => 'raw').tag 'raw_atom'
62
+ rule('letter_range' => 'LETTER FROM LETTER_LIT TO LETTER_LIT').tag 'lowercase_from_to'
63
+ rule('letter_range' => 'UPPERCASE LETTER FROM LETTER_LIT TO LETTER_LIT').tag 'uppercase_from_to'
64
+ rule('letter_range' => 'LETTER').tag 'any_lowercase'
65
+ rule('letter_range' => 'UPPERCASE LETTER').tag 'any_uppercase'
66
+ rule('digit_range' => 'digit_or_number FROM DIGIT_LIT TO DIGIT_LIT').tag 'digits_from_to'
67
+ rule('character_class' => 'ANY CHARACTER').tag 'any_character'
68
+ rule('character_class' => 'NO CHARACTER').tag 'no_character'
69
+ rule('character_class' => 'digit_or_number').tag 'digit'
70
+ rule('character_class' => 'NO DIGIT').tag 'non_digit'
71
+ rule('character_class' => 'WHITESPACE').tag 'whitespace'
72
+ rule('character_class' => 'NO WHITESPACE').tag 'no_whitespace'
73
+ rule('character_class' => 'ANYTHING').tag 'anything'
74
+ rule('character_class' => 'ONE OF cclass').tag 'one_of'
75
+ rule('character_class' => 'NONE OF cclass').tag 'none_of'
76
+ rule('cclass' => 'STRING_LIT').tag 'quoted_cclass' # Preferred syntax
77
+ rule('cclass' => 'INTEGER').tag 'digits_cclass'
78
+ rule('cclass' => 'IDENTIFIER').tag 'identifier_cclass'
79
+ rule('cclass' => 'CHAR_CLASS').tag 'unquoted_cclass'
80
+ rule('special_char' => 'TAB').tag 'tab'
81
+ rule('special_char' => 'VERTICAL TAB').tag 'vtab'
82
+ rule('special_char' => 'BACKSLASH').tag 'backslash'
83
+ rule('special_char' => 'NEW LINE').tag 'new_line'
84
+ rule('special_char' => 'CARRIAGE RETURN').tag 'carriage_return'
85
+ rule('special_char' => 'WORD').tag 'word'
86
+ rule('special_char' => 'NO WORD').tag 'no_word'
87
+ rule('literal' => 'LITERALLY STRING_LIT').tag 'literally'
88
+ rule('raw' => 'RAW STRING_LIT').tag 'raw_literal'
89
+ rule('alternation' => 'any_or_either OF LPAREN alternatives RPAREN').tag 'any_of'
90
+ rule('alternatives' => 'alternatives separator quantifiable').tag 'alternative_list'
91
+ rule('alternatives' => 'quantifiable').tag 'simple_alternative'
92
+ rule('any_or_either' => 'ANY').tag 'any_keyword'
93
+ rule('any_or_either' => 'EITHER').tag 'either_keyword'
94
+ rule('grouping' => 'LPAREN pattern RPAREN').tag 'grouping_parenthenses'
95
+ rule('capturing_group' => 'CAPTURE assertable (UNTIL assertable)?').tag 'capture'
96
+ rule('capturing_group' => 'CAPTURE assertable AS var_name (UNTIL assertable)?').tag 'named_capture'
97
+ rule('var_name' => 'STRING_LIT').tag 'var_name'
98
+ rule('var_name' => 'IDENTIFIER').tag 'var_ident' # capture name not enclosed between quotes
99
+ rule('quantifier' => 'ONCE').tag 'once'
100
+ rule('quantifier' => 'TWICE').tag 'twice'
101
+ rule('quantifier' => 'EXACTLY count TIMES').tag 'exactly'
102
+ rule('quantifier' => 'BETWEEN count AND count TIMES?').tag 'between_and'
103
+ rule('quantifier' => 'OPTIONAL').tag 'optional'
104
+ rule('quantifier' => 'ONCE OR MORE').tag 'once_or_more'
105
+ rule('quantifier' => 'NEVER OR MORE').tag 'never_or_more'
106
+ rule('quantifier' => 'AT LEAST count TIMES').tag 'at_least'
107
+ rule('digit_or_number' => 'DIGIT').tag 'digit_keyword'
108
+ rule('digit_or_number' => 'NUMBER').tag 'number_keyword'
109
+ rule('count' => 'DIGIT_LIT').tag 'single_digit'
110
+ rule('count' => 'INTEGER').tag 'integer_count'
125
111
  end
126
112
 
127
113
  # And now build the grammar and make it accessible via a global constant
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SrlRuby
4
- VERSION = '0.4.7'
4
+ VERSION = '0.4.8'
5
5
  end
data/srl_ruby.gemspec CHANGED
@@ -71,7 +71,7 @@ SUMMARY
71
71
  spec.add_dependency 'rley', '~> 0.8.02'
72
72
 
73
73
  # Development dependencies
74
- spec.add_development_dependency 'bundler', '~> 2.1.0'
74
+ spec.add_development_dependency 'bundler', '~> 2.2.0'
75
75
  spec.add_development_dependency 'cucumber', '>= 2.2.0'
76
76
  spec.add_development_dependency 'rake', '~> 12.0'
77
77
  spec.add_development_dependency 'rspec', '~> 3.0'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: srl_ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.7
4
+ version: 0.4.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitri Geshef
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-24 00:00:00.000000000 Z
11
+ date: 2021-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rley
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 2.1.0
33
+ version: 2.2.0
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 2.1.0
40
+ version: 2.2.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: cucumber
43
43
  requirement: !ruby/object:Gem::Requirement