srl_ruby 0.4.7 → 0.4.8

Sign up to get free protection for your applications and to get access to all the features.
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