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 +4 -4
- data/CHANGELOG.md +9 -0
- data/LICENSE.txt +1 -1
- data/lib/srl_ruby/ast_builder.rb +75 -119
- data/lib/srl_ruby/grammar.rb +77 -91
- data/lib/srl_ruby/version.rb +1 -1
- data/srl_ruby.gemspec +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4142454106f1b3b0a0e1e9b7c382ba6c5088f34a7b4d2e4c9437164537bb766a
|
4
|
+
data.tar.gz: 2ded972212dc2db8b037aba56aec6f79917a90a945f56c8f9f72b1bd88cd8b69
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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-
|
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
|
data/lib/srl_ruby/ast_builder.rb
CHANGED
@@ -118,70 +118,52 @@ module SrlRuby
|
|
118
118
|
Regex::Anchor.new('^')
|
119
119
|
end
|
120
120
|
|
121
|
-
# rule('expression' =>
|
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' =>
|
127
|
+
# rule('pattern' => 'subpattern (separator sub_pattern)*').tag 'pattern_sequence'
|
128
128
|
def reduce_pattern_sequence(_production, _range, _tokens, theChildren)
|
129
|
-
|
130
|
-
|
131
|
-
|
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],
|
135
|
+
Regex::Concatenation.new(theChildren[0], *successors)
|
134
136
|
end
|
135
137
|
end
|
136
138
|
|
137
|
-
# rule('
|
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' =>
|
144
|
+
# rule('flags' => '(separator single_flag)+').tag 'flag_sequence'
|
148
145
|
def reduce_flag_sequence(_production, _range, _tokens, theChildren)
|
149
|
-
theChildren[0]
|
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]).
|
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]).
|
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]).
|
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
|
173
|
-
def
|
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]).
|
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' =>
|
184
|
+
# rule('assertion' => 'IF NOT? FOLLOWED BY assertable')
|
203
185
|
def reduce_if_followed(_production, _range, _tokens, theChildren)
|
204
|
-
|
186
|
+
polarity = theChildren[1] ? :negative : :positive
|
187
|
+
Regex::Lookaround.new(theChildren.last, :ahead, polarity)
|
205
188
|
end
|
206
189
|
|
207
|
-
# rule('assertion' =>
|
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
|
-
|
192
|
+
polarity = theChildren[1] ? :negative : :positive
|
193
|
+
Regex::Lookaround.new(theChildren.last, :behind, polarity)
|
215
194
|
end
|
216
195
|
|
217
|
-
# rule('
|
218
|
-
def
|
219
|
-
|
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('
|
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]).
|
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').
|
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]).
|
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]).
|
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]).
|
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]).
|
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').
|
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]).
|
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').
|
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]).
|
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').
|
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]).
|
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]).
|
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').
|
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').
|
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').
|
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]).
|
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]).
|
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]).
|
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]).
|
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]).
|
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]).
|
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]).
|
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]).
|
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').
|
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]).
|
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' =>
|
431
|
-
#
|
432
|
-
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
|
+
|
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
|
-
|
407
|
+
(_, until_expr) = theChildren[2]
|
408
|
+
Regex::Concatenation.new(group, until_expr)
|
438
409
|
end
|
439
410
|
|
440
|
-
# rule('capturing_group' =>
|
441
|
-
#
|
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
|
-
|
420
|
+
(_, until_expr) = theChildren[4]
|
421
|
+
return Regex::Concatenation.new(group, until_expr)
|
456
422
|
end
|
457
423
|
|
458
|
-
# rule('quantifier' => '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').
|
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]).
|
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' =>
|
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').
|
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]).
|
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]).
|
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]).
|
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
|
data/lib/srl_ruby/grammar.rb
CHANGED
@@ -31,97 +31,83 @@ module SrlRuby
|
|
31
31
|
add_terminals('LAZY')
|
32
32
|
|
33
33
|
# Grammar rules...
|
34
|
-
rule('srl' => 'expression').
|
35
|
-
rule('expression' => 'pattern flags').
|
36
|
-
rule('
|
37
|
-
rule('
|
38
|
-
rule('
|
39
|
-
rule('
|
40
|
-
rule('
|
41
|
-
rule('
|
42
|
-
rule('
|
43
|
-
rule('
|
44
|
-
rule('
|
45
|
-
rule('
|
46
|
-
rule('
|
47
|
-
rule('
|
48
|
-
rule('
|
49
|
-
rule('
|
50
|
-
rule('
|
51
|
-
rule('
|
52
|
-
rule('
|
53
|
-
rule('
|
54
|
-
rule('
|
55
|
-
rule('
|
56
|
-
rule('
|
57
|
-
rule('
|
58
|
-
rule('
|
59
|
-
rule('
|
60
|
-
rule('
|
61
|
-
rule('
|
62
|
-
rule('
|
63
|
-
rule('
|
64
|
-
rule('
|
65
|
-
rule('
|
66
|
-
rule('
|
67
|
-
rule('
|
68
|
-
rule('
|
69
|
-
rule('
|
70
|
-
rule('
|
71
|
-
rule('
|
72
|
-
rule('
|
73
|
-
rule('
|
74
|
-
rule('
|
75
|
-
rule('
|
76
|
-
rule('
|
77
|
-
rule('
|
78
|
-
rule('
|
79
|
-
rule('
|
80
|
-
rule('
|
81
|
-
rule('
|
82
|
-
rule('
|
83
|
-
rule('
|
84
|
-
rule('
|
85
|
-
rule('
|
86
|
-
rule('
|
87
|
-
rule('
|
88
|
-
rule('
|
89
|
-
rule('
|
90
|
-
rule('
|
91
|
-
rule('
|
92
|
-
rule('
|
93
|
-
rule('
|
94
|
-
rule('
|
95
|
-
rule('
|
96
|
-
rule('
|
97
|
-
rule('
|
98
|
-
rule('
|
99
|
-
rule('
|
100
|
-
rule('
|
101
|
-
rule('
|
102
|
-
rule('
|
103
|
-
rule('
|
104
|
-
rule('
|
105
|
-
rule('
|
106
|
-
rule('
|
107
|
-
rule('
|
108
|
-
rule('
|
109
|
-
rule('
|
110
|
-
rule('
|
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
|
data/lib/srl_ruby/version.rb
CHANGED
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.
|
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.
|
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-
|
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.
|
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.
|
40
|
+
version: 2.2.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: cucumber
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|