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 +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
|