regexp_parser 1.5.0 → 1.8.0
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 +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,
|