regexp_parser 1.5.0 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +59 -0
- data/Gemfile +3 -3
- data/README.md +14 -6
- data/Rakefile +3 -4
- data/lib/regexp_parser/expression.rb +6 -43
- data/lib/regexp_parser/expression/classes/conditional.rb +3 -2
- data/lib/regexp_parser/expression/classes/escape.rb +0 -4
- data/lib/regexp_parser/expression/methods/match.rb +13 -0
- data/lib/regexp_parser/expression/methods/match_length.rb +1 -1
- data/lib/regexp_parser/expression/methods/options.rb +35 -0
- data/lib/regexp_parser/expression/methods/strfregexp.rb +0 -1
- data/lib/regexp_parser/expression/methods/tests.rb +6 -15
- data/lib/regexp_parser/expression/methods/traverse.rb +3 -1
- data/lib/regexp_parser/expression/sequence.rb +3 -2
- data/lib/regexp_parser/expression/sequence_operation.rb +2 -6
- data/lib/regexp_parser/lexer.rb +4 -25
- data/lib/regexp_parser/parser.rb +40 -33
- data/lib/regexp_parser/scanner.rb +1208 -1353
- data/lib/regexp_parser/scanner/char_type.rl +0 -3
- data/lib/regexp_parser/scanner/properties/long.yml +15 -1
- data/lib/regexp_parser/scanner/properties/short.yml +5 -0
- data/lib/regexp_parser/scanner/scanner.rl +116 -202
- data/lib/regexp_parser/syntax/tokens/unicode_property.rb +30 -0
- data/lib/regexp_parser/syntax/versions/2.6.2.rb +10 -0
- data/lib/regexp_parser/syntax/versions/2.6.3.rb +10 -0
- data/lib/regexp_parser/version.rb +1 -1
- data/spec/expression/base_spec.rb +14 -0
- data/spec/expression/methods/match_length_spec.rb +20 -0
- data/spec/expression/methods/match_spec.rb +25 -0
- data/spec/expression/methods/tests_spec.rb +2 -0
- data/spec/expression/methods/traverse_spec.rb +21 -0
- data/spec/expression/options_spec.rb +128 -0
- data/spec/expression/root_spec.rb +9 -0
- data/spec/expression/sequence_spec.rb +9 -0
- data/spec/lexer/conditionals_spec.rb +49 -119
- data/spec/lexer/delimiters_spec.rb +68 -0
- data/spec/lexer/escapes_spec.rb +8 -32
- data/spec/lexer/keep_spec.rb +5 -17
- data/spec/lexer/literals_spec.rb +73 -110
- data/spec/lexer/nesting_spec.rb +86 -117
- data/spec/lexer/refcalls_spec.rb +51 -50
- data/spec/parser/all_spec.rb +13 -1
- data/spec/parser/anchors_spec.rb +9 -23
- data/spec/parser/conditionals_spec.rb +9 -9
- data/spec/parser/errors_spec.rb +22 -43
- data/spec/parser/escapes_spec.rb +33 -44
- data/spec/parser/free_space_spec.rb +25 -4
- data/spec/parser/groups_spec.rb +98 -257
- data/spec/parser/keep_spec.rb +2 -15
- data/spec/parser/options_spec.rb +28 -0
- data/spec/parser/posix_classes_spec.rb +5 -24
- data/spec/parser/properties_spec.rb +42 -54
- data/spec/parser/quantifiers_spec.rb +42 -283
- data/spec/parser/refcalls_spec.rb +60 -185
- data/spec/parser/set/intersections_spec.rb +17 -17
- data/spec/parser/set/ranges_spec.rb +17 -17
- data/spec/parser/sets_spec.rb +5 -5
- data/spec/parser/types_spec.rb +11 -36
- data/spec/scanner/anchors_spec.rb +13 -28
- data/spec/scanner/conditionals_spec.rb +121 -173
- data/spec/scanner/delimiters_spec.rb +52 -0
- data/spec/scanner/errors_spec.rb +64 -87
- data/spec/scanner/escapes_spec.rb +53 -50
- data/spec/scanner/free_space_spec.rb +102 -165
- data/spec/scanner/groups_spec.rb +45 -64
- data/spec/scanner/keep_spec.rb +5 -28
- data/spec/scanner/literals_spec.rb +45 -81
- data/spec/scanner/meta_spec.rb +13 -33
- data/spec/scanner/options_spec.rb +36 -0
- data/spec/scanner/properties_spec.rb +43 -286
- data/spec/scanner/quantifiers_spec.rb +13 -28
- data/spec/scanner/refcalls_spec.rb +32 -48
- data/spec/scanner/sets_spec.rb +88 -102
- data/spec/scanner/types_spec.rb +10 -25
- data/spec/spec_helper.rb +1 -0
- data/spec/support/shared_examples.rb +77 -0
- data/spec/syntax/syntax_spec.rb +4 -0
- data/spec/syntax/versions/1.8.6_spec.rb +12 -33
- data/spec/syntax/versions/1.9.1_spec.rb +5 -18
- data/spec/syntax/versions/1.9.3_spec.rb +4 -17
- data/spec/syntax/versions/2.0.0_spec.rb +8 -23
- data/spec/syntax/versions/2.2.0_spec.rb +4 -17
- data/spec/syntax/versions/aliases_spec.rb +27 -109
- metadata +28 -10
- data/spec/scanner/scripts_spec.rb +0 -49
- data/spec/scanner/unicode_blocks_spec.rb +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c8e3ba5269d32f57fdcad4ba98f16bc88b74713106a23f63ba2728fa89cf802
|
4
|
+
data.tar.gz: bbb1fe8c3f72b750a707a9f6c237c752455b4cd34d2bc8b0f255284fd32d4ed3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 93f94773ee6cb173771608ecdaf67e9e444e1ba7922cd97b8124a6ec90868e94b484ad6bdd0599d9ae9c2247e2a1627cdb03c620ce85f62d320ba8b1fdbb63bb
|
7
|
+
data.tar.gz: 9e1927e7c10d182bce099f24964f8c7e88ac76d479d22c632ab09406bc37711c9cc78af53892d46b009d0f12c8c3ffcd2221b2a1b2ca5365b3d3c1797448f3f2
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,64 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
### [1.8.0] - 2020-09-20 - [Janosch Müller](mailto:janosch84@gmail.com)
|
4
|
+
|
5
|
+
### Changed
|
6
|
+
|
7
|
+
- dropped support for running on Ruby 1.9.x
|
8
|
+
|
9
|
+
### Added
|
10
|
+
|
11
|
+
- regexp flags can now be passed when parsing a `String` as regexp body
|
12
|
+
* see the [README](/README.md#usage) for details
|
13
|
+
* thanks to [Owen Stephens](https://github.com/owst)
|
14
|
+
- bare occurrences of `\g` and `\k` are now allowed and scanned as literal escapes
|
15
|
+
* matches Onigmo behavior
|
16
|
+
* thanks for the report to [Marc-André Lafortune](https://github.com/marcandre)
|
17
|
+
|
18
|
+
### Fixed
|
19
|
+
|
20
|
+
- fixed parsing comments without preceding space or trailing newline in x-mode
|
21
|
+
* thanks to [Owen Stephens](https://github.com/owst)
|
22
|
+
|
23
|
+
### [1.7.1] - 2020-06-07 - [Ammar Ali](mailto:ammarabuali@gmail.com)
|
24
|
+
|
25
|
+
### Fixed
|
26
|
+
|
27
|
+
- Support for literals that include the unescaped delimiters `{`, `}`, and `]`. These
|
28
|
+
delimiters are informally supported by various regexp engines.
|
29
|
+
|
30
|
+
### [1.7.0] - 2020-02-23 - [Janosch Müller](mailto:janosch84@gmail.com)
|
31
|
+
|
32
|
+
### Added
|
33
|
+
|
34
|
+
- `Expression#each_expression` and `#traverse` can now be called without a block
|
35
|
+
* this returns an `Enumerator` and allows chaining, e.g. `each_expression.select`
|
36
|
+
* thanks to [Masataka Kuwabara](https://github.com/pocke)
|
37
|
+
|
38
|
+
### Fixed
|
39
|
+
|
40
|
+
- `MatchLength#each` no longer ignores the given `limit:` when called without a block
|
41
|
+
|
42
|
+
### [1.6.0] - 2019-06-16 - [Janosch Müller](mailto:janosch84@gmail.com)
|
43
|
+
|
44
|
+
### Added
|
45
|
+
|
46
|
+
- Added support for 16 new unicode properties introduced in Ruby 2.6.2 and 2.6.3
|
47
|
+
|
48
|
+
### [1.5.1] - 2019-05-23 - [Janosch Müller](mailto:janosch84@gmail.com)
|
49
|
+
|
50
|
+
### Fixed
|
51
|
+
|
52
|
+
- Fixed `#options` (and thus `#i?`, `#u?` etc.) not being set for some expressions:
|
53
|
+
* this affected posix classes as well as alternation, conditional, and intersection branches
|
54
|
+
* `#options` was already correct for all child expressions of such branches
|
55
|
+
* this only made an operational difference for posix classes as they respect encoding flags
|
56
|
+
- Fixed `#options` not respecting all negative options in weird cases like '(?u-m-x)'
|
57
|
+
- Fixed `Group#option_changes` not accounting for indirectly disabled (overridden) encoding flags
|
58
|
+
- Fixed `Scanner` allowing negative encoding options if there were no positive options, e.g. '(?-u)'
|
59
|
+
- Fixed `ScannerError` for some valid meta/control sequences such as '\\C-\\\\'
|
60
|
+
- Fixed `Expression#match` and `#=~` not working with a single argument
|
61
|
+
|
3
62
|
### [1.5.0] - 2019-05-14 - [Janosch Müller](mailto:janosch84@gmail.com)
|
4
63
|
|
5
64
|
### Added
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -8,7 +8,7 @@ A Ruby gem for tokenizing, parsing, and transforming regular expressions.
|
|
8
8
|
* A scanner/tokenizer based on [Ragel](http://www.colm.net/open-source/ragel/)
|
9
9
|
* A lexer that produces a "stream" of token objects.
|
10
10
|
* A parser that produces a "tree" of Expression objects (OO API)
|
11
|
-
* Runs on Ruby
|
11
|
+
* Runs on Ruby 2.x and JRuby runtimes
|
12
12
|
* Recognizes Ruby 1.8, 1.9, and 2.x regular expressions [See Supported Syntax](#supported-syntax)
|
13
13
|
|
14
14
|
|
@@ -72,6 +72,17 @@ called with the results as follows:
|
|
72
72
|
* **Parser**: after completion, the block gets passed the root expression.
|
73
73
|
_The result of the block is returned._
|
74
74
|
|
75
|
+
All three methods accept either a `Regexp` or `String` (containing the pattern)
|
76
|
+
- if a String is passed, `options` can be supplied:
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
require 'regexp_parser'
|
80
|
+
|
81
|
+
Regexp::Parser.parse(
|
82
|
+
"a+ # Recognises a and A...",
|
83
|
+
options: ::Regexp::EXTENDED | ::Regexp::IGNORECASE
|
84
|
+
)
|
85
|
+
```
|
75
86
|
|
76
87
|
---
|
77
88
|
## Components
|
@@ -136,11 +147,8 @@ Regexp::Scanner.scan( /(cat?([bhm]at)){3,5}/ ).map {|token| token[2]}
|
|
136
147
|
to the lexer.
|
137
148
|
|
138
149
|
* The MRI implementation may accept expressions that either conflict with
|
139
|
-
the documentation or are undocumented
|
140
|
-
|
141
|
-
_(See issues [#3](https://github.com/ammar/regexp_parser/issues/3) and
|
142
|
-
[#15](https://github.com/ammar/regexp_parser/issues/15) for examples)_
|
143
|
-
|
150
|
+
the documentation or are undocumented, like `{}` and `]` _(unescaped)_.
|
151
|
+
The scanner will try to support as many of these cases as possible.
|
144
152
|
|
145
153
|
---
|
146
154
|
### Syntax
|
data/Rakefile
CHANGED
@@ -74,14 +74,13 @@ namespace :props do
|
|
74
74
|
puts "Wrote #{hash.count} aliases to `#{path}`"
|
75
75
|
end
|
76
76
|
|
77
|
-
|
78
|
-
|
79
|
-
[name.downcase.gsub(/[^0-9a-z=.]/, ''), name.downcase]
|
77
|
+
long_names_to_tokens = RegexpPropertyValues.all.map do |val|
|
78
|
+
[val.identifier, val.full_name.downcase]
|
80
79
|
end
|
81
80
|
write_hash_to_file.call(long_names_to_tokens, "#{dir}/long.yml")
|
82
81
|
|
83
82
|
short_names_to_tokens = RegexpPropertyValues.alias_hash.map do |k, v|
|
84
|
-
[k.
|
83
|
+
[k.identifier, v.full_name.downcase]
|
85
84
|
end
|
86
85
|
write_hash_to_file.call(short_names_to_tokens, "#{dir}/short.yml")
|
87
86
|
end
|
@@ -97,47 +97,6 @@ module Regexp::Expression
|
|
97
97
|
quantified? and quantifier.possessive?
|
98
98
|
end
|
99
99
|
|
100
|
-
def multiline?
|
101
|
-
options[:m] == true
|
102
|
-
end
|
103
|
-
alias :m? :multiline?
|
104
|
-
|
105
|
-
def case_insensitive?
|
106
|
-
options[:i] == true
|
107
|
-
end
|
108
|
-
alias :i? :case_insensitive?
|
109
|
-
alias :ignore_case? :case_insensitive?
|
110
|
-
|
111
|
-
def free_spacing?
|
112
|
-
options[:x] == true
|
113
|
-
end
|
114
|
-
alias :x? :free_spacing?
|
115
|
-
alias :extended? :free_spacing?
|
116
|
-
|
117
|
-
def default_classes?
|
118
|
-
options[:d] == true
|
119
|
-
end
|
120
|
-
alias :d? :default_classes?
|
121
|
-
|
122
|
-
def ascii_classes?
|
123
|
-
options[:a] == true
|
124
|
-
end
|
125
|
-
alias :a? :ascii_classes?
|
126
|
-
|
127
|
-
def unicode_classes?
|
128
|
-
options[:u] == true
|
129
|
-
end
|
130
|
-
alias :u? :unicode_classes?
|
131
|
-
|
132
|
-
def matches?(string)
|
133
|
-
Regexp.new(to_s) =~ string ? true : false
|
134
|
-
end
|
135
|
-
|
136
|
-
def match(string, offset)
|
137
|
-
Regexp.new(to_s).match(string, offset)
|
138
|
-
end
|
139
|
-
alias :=~ :match
|
140
|
-
|
141
100
|
def attributes
|
142
101
|
{
|
143
102
|
type: type,
|
@@ -156,12 +115,14 @@ module Regexp::Expression
|
|
156
115
|
end
|
157
116
|
|
158
117
|
def self.parsed(exp)
|
118
|
+
warn('WARNING: Regexp::Expression::Base.parsed is buggy and '\
|
119
|
+
'will be removed in 2.0.0. Use Regexp::Parser.parse instead.')
|
159
120
|
case exp
|
160
121
|
when String
|
161
122
|
Regexp::Parser.parse(exp)
|
162
123
|
when Regexp
|
163
|
-
Regexp::Parser.parse(exp.source)
|
164
|
-
when Regexp::Expression
|
124
|
+
Regexp::Parser.parse(exp.source) # <- causes loss of root options
|
125
|
+
when Regexp::Expression # <- never triggers
|
165
126
|
exp
|
166
127
|
else
|
167
128
|
raise ArgumentError, 'Expression.parsed accepts a String, Regexp, or '\
|
@@ -194,7 +155,9 @@ require 'regexp_parser/expression/classes/set/intersection'
|
|
194
155
|
require 'regexp_parser/expression/classes/set/range'
|
195
156
|
require 'regexp_parser/expression/classes/type'
|
196
157
|
|
158
|
+
require 'regexp_parser/expression/methods/match'
|
197
159
|
require 'regexp_parser/expression/methods/match_length'
|
160
|
+
require 'regexp_parser/expression/methods/options'
|
198
161
|
require 'regexp_parser/expression/methods/strfregexp'
|
199
162
|
require 'regexp_parser/expression/methods/tests'
|
200
163
|
require 'regexp_parser/expression/methods/traverse'
|
@@ -26,9 +26,10 @@ module Regexp::Expression
|
|
26
26
|
expressions.last << exp
|
27
27
|
end
|
28
28
|
|
29
|
-
def add_sequence
|
29
|
+
def add_sequence(active_opts = {})
|
30
30
|
raise TooManyBranches.new if branches.length == 2
|
31
|
-
|
31
|
+
params = { conditional_level: conditional_level + 1 }
|
32
|
+
Branch.add_to(self, params, active_opts)
|
32
33
|
end
|
33
34
|
alias :branch :add_sequence
|
34
35
|
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Regexp::Expression
|
2
|
+
class Base
|
3
|
+
def multiline?
|
4
|
+
options[:m] == true
|
5
|
+
end
|
6
|
+
alias :m? :multiline?
|
7
|
+
|
8
|
+
def case_insensitive?
|
9
|
+
options[:i] == true
|
10
|
+
end
|
11
|
+
alias :i? :case_insensitive?
|
12
|
+
alias :ignore_case? :case_insensitive?
|
13
|
+
|
14
|
+
def free_spacing?
|
15
|
+
options[:x] == true
|
16
|
+
end
|
17
|
+
alias :x? :free_spacing?
|
18
|
+
alias :extended? :free_spacing?
|
19
|
+
|
20
|
+
def default_classes?
|
21
|
+
options[:d] == true
|
22
|
+
end
|
23
|
+
alias :d? :default_classes?
|
24
|
+
|
25
|
+
def ascii_classes?
|
26
|
+
options[:a] == true
|
27
|
+
end
|
28
|
+
alias :a? :ascii_classes?
|
29
|
+
|
30
|
+
def unicode_classes?
|
31
|
+
options[:u] == true
|
32
|
+
end
|
33
|
+
alias :u? :unicode_classes?
|
34
|
+
end
|
35
|
+
end
|
@@ -75,32 +75,23 @@ module Regexp::Expression
|
|
75
75
|
def one_of?(scope, top = true)
|
76
76
|
case scope
|
77
77
|
when Array
|
78
|
-
|
79
|
-
return (scope.include?(token) or scope.include?(:*))
|
80
|
-
else
|
81
|
-
return scope.include?(token)
|
82
|
-
end
|
78
|
+
scope.include?(:*) || scope.include?(token)
|
83
79
|
|
84
80
|
when Hash
|
85
81
|
if scope.has_key?(:*)
|
86
82
|
test_type = scope.has_key?(type) ? type : :*
|
87
|
-
|
83
|
+
one_of?(scope[test_type], false)
|
88
84
|
else
|
89
|
-
|
85
|
+
scope.has_key?(type) && one_of?(scope[type], false)
|
90
86
|
end
|
91
87
|
|
92
88
|
when Symbol
|
93
|
-
|
94
|
-
|
95
|
-
return is?(scope) unless top
|
96
|
-
return type?(scope) if top
|
89
|
+
scope.equal?(:*) || (top ? type?(scope) : is?(scope))
|
97
90
|
|
98
91
|
else
|
99
|
-
raise
|
92
|
+
raise ArgumentError,
|
93
|
+
"Array, Hash, or Symbol expected, #{scope.class.name} given"
|
100
94
|
end
|
101
|
-
|
102
|
-
false
|
103
95
|
end
|
104
|
-
|
105
96
|
end
|
106
97
|
end
|
@@ -14,7 +14,7 @@ module Regexp::Expression
|
|
14
14
|
#
|
15
15
|
# Returns self.
|
16
16
|
def traverse(include_self = false, &block)
|
17
|
-
|
17
|
+
return enum_for(__method__, include_self) unless block_given?
|
18
18
|
|
19
19
|
block.call(:enter, self, 0) if include_self
|
20
20
|
|
@@ -37,6 +37,8 @@ module Regexp::Expression
|
|
37
37
|
# Iterates over the expressions of this expression as an array, passing
|
38
38
|
# the expression and its index within its parent to the given block.
|
39
39
|
def each_expression(include_self = false, &block)
|
40
|
+
return enum_for(__method__, include_self) unless block_given?
|
41
|
+
|
40
42
|
traverse(include_self) do |event, exp, index|
|
41
43
|
yield(exp, index) unless event == :exit
|
42
44
|
end
|
@@ -18,13 +18,14 @@ module Regexp::Expression
|
|
18
18
|
end
|
19
19
|
|
20
20
|
class << self
|
21
|
-
def add_to(subexpression,
|
21
|
+
def add_to(subexpression, params = {}, active_opts = {})
|
22
22
|
sequence = at_levels(
|
23
23
|
subexpression.level,
|
24
24
|
subexpression.set_level,
|
25
|
-
|
25
|
+
params[:conditional_level] || subexpression.conditional_level
|
26
26
|
)
|
27
27
|
sequence.nesting_level = subexpression.nesting_level + 1
|
28
|
+
sequence.options = active_opts
|
28
29
|
subexpression.expressions << sequence
|
29
30
|
sequence
|
30
31
|
end
|
@@ -14,12 +14,8 @@ module Regexp::Expression
|
|
14
14
|
expressions.last << exp
|
15
15
|
end
|
16
16
|
|
17
|
-
def add_sequence
|
18
|
-
self.class::OPERAND.add_to(self)
|
19
|
-
end
|
20
|
-
|
21
|
-
def quantify(token, text, min = nil, max = nil, mode = :greedy)
|
22
|
-
sequences.last.last.quantify(token, text, min, max, mode)
|
17
|
+
def add_sequence(active_opts = {})
|
18
|
+
self.class::OPERAND.add_to(self, {}, active_opts)
|
23
19
|
end
|
24
20
|
|
25
21
|
def to_s(format = :full)
|
data/lib/regexp_parser/lexer.rb
CHANGED
@@ -11,11 +11,11 @@ class Regexp::Lexer
|
|
11
11
|
|
12
12
|
CLOSING_TOKENS = [:close].freeze
|
13
13
|
|
14
|
-
def self.lex(input, syntax = "ruby/#{RUBY_VERSION}", &block)
|
15
|
-
new.lex(input, syntax, &block)
|
14
|
+
def self.lex(input, syntax = "ruby/#{RUBY_VERSION}", options: nil, &block)
|
15
|
+
new.lex(input, syntax, options: options, &block)
|
16
16
|
end
|
17
17
|
|
18
|
-
def lex(input, syntax = "ruby/#{RUBY_VERSION}", &block)
|
18
|
+
def lex(input, syntax = "ruby/#{RUBY_VERSION}", options: nil, &block)
|
19
19
|
syntax = Regexp::Syntax.new(syntax)
|
20
20
|
|
21
21
|
self.tokens = []
|
@@ -25,7 +25,7 @@ class Regexp::Lexer
|
|
25
25
|
self.shift = 0
|
26
26
|
|
27
27
|
last = nil
|
28
|
-
Regexp::Scanner.scan(input) do |type, token, text, ts, te|
|
28
|
+
Regexp::Scanner.scan(input, options: options) do |type, token, text, ts, te|
|
29
29
|
type, token = *syntax.normalize(type, token)
|
30
30
|
syntax.check! type, token
|
31
31
|
|
@@ -39,10 +39,6 @@ class Regexp::Lexer
|
|
39
39
|
current = Regexp::Token.new(type, token, text, ts + shift, te + shift,
|
40
40
|
nesting, set_nesting, conditional_nesting)
|
41
41
|
|
42
|
-
current = merge_literal(current) if type == :literal and
|
43
|
-
set_nesting == 0 and
|
44
|
-
last and last.type == :literal
|
45
|
-
|
46
42
|
current = merge_condition(current) if type == :conditional and
|
47
43
|
[:condition, :condition_close].include?(token)
|
48
44
|
|
@@ -122,23 +118,6 @@ class Regexp::Lexer
|
|
122
118
|
self.shift = shift + 3 # one space less, but extra \, u, {, and }
|
123
119
|
end
|
124
120
|
|
125
|
-
# called by scan to merge two consecutive literals. this happens when tokens
|
126
|
-
# get normalized (as in the case of posix/bre) and end up becoming literals.
|
127
|
-
def merge_literal(current)
|
128
|
-
last = tokens.pop
|
129
|
-
|
130
|
-
Regexp::Token.new(
|
131
|
-
:literal,
|
132
|
-
:literal,
|
133
|
-
last.text + current.text,
|
134
|
-
last.ts,
|
135
|
-
current.te,
|
136
|
-
nesting,
|
137
|
-
set_nesting,
|
138
|
-
conditional_nesting,
|
139
|
-
)
|
140
|
-
end
|
141
|
-
|
142
121
|
def merge_condition(current)
|
143
122
|
last = tokens.pop
|
144
123
|
Regexp::Token.new(:conditional, :condition, last.text + current.text,
|