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