regexp_parser 1.8.2 → 2.1.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 +93 -0
- data/Gemfile +6 -1
- data/README.md +1 -4
- data/Rakefile +8 -8
- data/lib/regexp_parser.rb +1 -0
- data/lib/regexp_parser/error.rb +4 -0
- data/lib/regexp_parser/expression.rb +5 -18
- data/lib/regexp_parser/expression/classes/backref.rb +5 -0
- data/lib/regexp_parser/expression/classes/conditional.rb +11 -1
- data/lib/regexp_parser/expression/classes/free_space.rb +2 -2
- data/lib/regexp_parser/expression/classes/group.rb +28 -3
- data/lib/regexp_parser/expression/classes/property.rb +1 -1
- data/lib/regexp_parser/expression/classes/root.rb +4 -16
- data/lib/regexp_parser/expression/classes/set/range.rb +2 -1
- data/lib/regexp_parser/expression/methods/match_length.rb +2 -2
- data/lib/regexp_parser/expression/methods/traverse.rb +2 -2
- data/lib/regexp_parser/expression/quantifier.rb +10 -1
- data/lib/regexp_parser/expression/sequence.rb +3 -19
- data/lib/regexp_parser/expression/subexpression.rb +1 -1
- data/lib/regexp_parser/lexer.rb +2 -2
- data/lib/regexp_parser/parser.rb +306 -332
- data/lib/regexp_parser/scanner.rb +1272 -1338
- data/lib/regexp_parser/scanner/char_type.rl +11 -11
- data/lib/regexp_parser/scanner/property.rl +2 -2
- data/lib/regexp_parser/scanner/scanner.rl +206 -238
- data/lib/regexp_parser/syntax.rb +7 -7
- data/lib/regexp_parser/syntax/any.rb +3 -3
- data/lib/regexp_parser/syntax/base.rb +1 -1
- data/lib/regexp_parser/syntax/version_lookup.rb +2 -2
- data/lib/regexp_parser/syntax/versions.rb +1 -1
- data/lib/regexp_parser/version.rb +1 -1
- data/spec/expression/base_spec.rb +10 -0
- data/spec/expression/clone_spec.rb +36 -4
- data/spec/expression/free_space_spec.rb +2 -2
- data/spec/expression/methods/match_length_spec.rb +2 -2
- data/spec/expression/subexpression_spec.rb +1 -1
- data/spec/expression/to_s_spec.rb +39 -31
- data/spec/lexer/literals_spec.rb +24 -49
- data/spec/lexer/refcalls_spec.rb +5 -0
- data/spec/parser/all_spec.rb +2 -2
- data/spec/parser/errors_spec.rb +1 -1
- data/spec/parser/escapes_spec.rb +1 -1
- data/spec/parser/quantifiers_spec.rb +16 -0
- data/spec/parser/refcalls_spec.rb +5 -0
- data/spec/parser/set/ranges_spec.rb +3 -3
- data/spec/scanner/escapes_spec.rb +8 -1
- data/spec/scanner/groups_spec.rb +10 -1
- data/spec/scanner/literals_spec.rb +28 -38
- data/spec/scanner/quantifiers_spec.rb +18 -13
- data/spec/scanner/refcalls_spec.rb +19 -0
- data/spec/scanner/sets_spec.rb +65 -16
- data/spec/spec_helper.rb +1 -0
- metadata +4 -7
- data/spec/expression/root_spec.rb +0 -9
- data/spec/expression/sequence_spec.rb +0 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 79c8b7838ef53335c9d0fbd21ffdf6815473ee560380a3687e8fab514d031d53
|
|
4
|
+
data.tar.gz: 2a91f7c7640fc5f2d304c2cbf240886d8e8642994861a9c092f1d4db2ae6b77a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3559a8c7af9c0087ab7a54862c9913e40a3703ffa23f62e6919eec50042523424c2aa4c99b3de9d28d03fc0edd14af37e0dcd0eab7bf822b9af73113be468b59
|
|
7
|
+
data.tar.gz: 31ed468565bd41fe2d0bd7b82d53d64e213a15e1ade2108ddf813637c228c18f6f7b456725c7e359a08754188ee19c90d06e013be90775ee6a64723b04fa25f0
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,98 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [2.1.0] - 2021-02-22 - [Janosch Müller](mailto:janosch84@gmail.com)
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- common ancestor for all scanning/parsing/lexing errors
|
|
8
|
+
* `Regexp::Parser::Error` can now be rescued as a catch-all
|
|
9
|
+
* the following errors (and their many descendants) now inherit from it:
|
|
10
|
+
- `Regexp::Expression::Conditional::TooManyBranches`
|
|
11
|
+
- `Regexp::Parser::ParserError`
|
|
12
|
+
- `Regexp::Scanner::ScannerError`
|
|
13
|
+
- `Regexp::Scanner::ValidationError`
|
|
14
|
+
- `Regexp::Syntax::SyntaxError`
|
|
15
|
+
* it replaces `ArgumentError` in some rare cases (`Regexp::Parser.parse('?')`)
|
|
16
|
+
* thanks to [sandstrom](https://github.com/sandstrom) for the cue
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- fixed scanning of whole-pattern recursion calls `\g<0>` and `\g'0'`
|
|
21
|
+
* a regression in v2.0.1 had caused them to be scanned as literals
|
|
22
|
+
- fixed scanning of some backreference and subexpression call edge cases
|
|
23
|
+
* e.g. `\k<+1>`, `\g<x-1>`
|
|
24
|
+
- fixed tokenization of some escapes in character sets
|
|
25
|
+
* `.`, `|`, `{`, `}`, `(`, `)`, `^`, `$`, `?`, `+`, `*`
|
|
26
|
+
* all of these correctly emitted `#type` `:literal` and `#token` `:literal` if *not* escaped
|
|
27
|
+
* if escaped, they emitted e.g. `#type` `:escape` and `#token` `:group_open` for `[\(]`
|
|
28
|
+
* the escaped versions now correctly emit `#type` `:escape` and `#token` `:literal`
|
|
29
|
+
- fixed handling of control/metacontrol escapes in character sets
|
|
30
|
+
* e.g. `[\cX]`, `[\M-\C-X]`
|
|
31
|
+
* they were misread as bunch of individual literals, escapes, and ranges
|
|
32
|
+
- fixed some cases where calling `#dup`/`#clone` on expressions led to shared state
|
|
33
|
+
|
|
34
|
+
## [2.0.3] - 2020-12-28 - [Janosch Müller](mailto:janosch84@gmail.com)
|
|
35
|
+
|
|
36
|
+
### Fixed
|
|
37
|
+
|
|
38
|
+
- fixed error when scanning some unlikely and redundant but valid charset patterns
|
|
39
|
+
* e.g. `/[[.a-b.]]/`, `/[[=e=]]/`,
|
|
40
|
+
- fixed ancestry of some error classes related to syntax version lookup
|
|
41
|
+
* `NotImplementedError`, `InvalidVersionNameError`, `UnknownSyntaxNameError`
|
|
42
|
+
* they now correctly inherit from `Regexp::Syntax::SyntaxError` instead of Rubys `::SyntaxError`
|
|
43
|
+
|
|
44
|
+
## [2.0.2] - 2020-12-25 - [Janosch Müller](mailto:janosch84@gmail.com)
|
|
45
|
+
|
|
46
|
+
### Fixed
|
|
47
|
+
|
|
48
|
+
- fixed `FrozenError` when calling `#to_s` on a frozen `Group::Passive`
|
|
49
|
+
* thanks to [Daniel Gollahon](https://github.com/dgollahon)
|
|
50
|
+
|
|
51
|
+
## [2.0.1] - 2020-12-20 - [Janosch Müller](mailto:janosch84@gmail.com)
|
|
52
|
+
|
|
53
|
+
### Fixed
|
|
54
|
+
|
|
55
|
+
- fixed error when scanning some group names
|
|
56
|
+
* this affected names containing hyphens, digits or multibyte chars, e.g. `/(?<a1>a)/`
|
|
57
|
+
* thanks to [Daniel Gollahon](https://github.com/dgollahon) for the report
|
|
58
|
+
- fixed error when scanning hex escapes with just one hex digit
|
|
59
|
+
* e.g. `/\x0A/` was scanned correctly, but the equivalent `/\xA/` was not
|
|
60
|
+
* thanks to [Daniel Gollahon](https://github.com/dgollahon) for the report
|
|
61
|
+
|
|
62
|
+
## [2.0.0] - 2020-11-25 - [Janosch Müller](mailto:janosch84@gmail.com)
|
|
63
|
+
|
|
64
|
+
### Changed
|
|
65
|
+
|
|
66
|
+
- some methods that used to return byte-based indices now return char-based indices
|
|
67
|
+
* the returned values have only changed for Regexps that contain multibyte chars
|
|
68
|
+
* this is only a breaking change if you used such methods directly AND relied on them pointing to bytes
|
|
69
|
+
* affected methods:
|
|
70
|
+
* `Regexp::Token` `#length`, `#offset`, `#te`, `#ts`
|
|
71
|
+
* `Regexp::Expression::Base` `#full_length`, `#offset`, `#starts_at`, `#te`, `#ts`
|
|
72
|
+
* thanks to [Akinori MUSHA](https://github.com/knu) for the report
|
|
73
|
+
- removed some deprecated methods/signatures
|
|
74
|
+
* these are rarely used and have been showing deprecation warnings for a long time
|
|
75
|
+
* `Regexp::Expression::Subexpression.new` with 3 arguments
|
|
76
|
+
* `Regexp::Expression::Root.new` without a token argument
|
|
77
|
+
* `Regexp::Expression.parsed`
|
|
78
|
+
|
|
79
|
+
### Added
|
|
80
|
+
|
|
81
|
+
- `Regexp::Expression::Base#base_length`
|
|
82
|
+
* returns the character count of an expression body, ignoring any quantifier
|
|
83
|
+
- pragmatic, experimental support for chained quantifiers
|
|
84
|
+
* e.g.: `/^a{10}{4,6}$/` matches exactly 40, 50 or 60 `a`s
|
|
85
|
+
* successive quantifiers used to be silently dropped by the parser
|
|
86
|
+
* they are now wrapped with passive groups as if they were written `(?:a{10}){4,6}`
|
|
87
|
+
* thanks to [calfeld](https://github.com/calfeld) for reporting this a while back
|
|
88
|
+
|
|
89
|
+
### Fixed
|
|
90
|
+
|
|
91
|
+
- incorrect encoding output for non-ascii comments
|
|
92
|
+
* this led to a crash when calling `#to_s` on parse results containing such comments
|
|
93
|
+
* thanks to [Michael Glass](https://github.com/michaelglass) for the report
|
|
94
|
+
- some crashes when scanning contrived patterns such as `'\😋'`
|
|
95
|
+
|
|
3
96
|
### [1.8.2] - 2020-10-11 - [Janosch Müller](mailto:janosch84@gmail.com)
|
|
4
97
|
|
|
5
98
|
### Fixed
|
data/Gemfile
CHANGED
|
@@ -3,7 +3,12 @@ source 'https://rubygems.org'
|
|
|
3
3
|
gemspec
|
|
4
4
|
|
|
5
5
|
group :development, :test do
|
|
6
|
+
gem 'ice_nine', '~> 0.11.2'
|
|
6
7
|
gem 'rake', '~> 13.0'
|
|
7
8
|
gem 'regexp_property_values', '~> 1.0'
|
|
8
|
-
gem 'rspec', '~> 3.
|
|
9
|
+
gem 'rspec', '~> 3.10'
|
|
10
|
+
if RUBY_VERSION.to_f >= 2.7
|
|
11
|
+
gem 'gouteur'
|
|
12
|
+
gem 'rubocop', '~> 1.7'
|
|
13
|
+
end
|
|
9
14
|
end
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Regexp::Parser
|
|
2
2
|
|
|
3
|
-
[](http://badge.fury.io/rb/regexp_parser) [](http://badge.fury.io/rb/regexp_parser) [](https://github.com/ammar/regexp_parser/actions) [](https://github.com/ammar/regexp_parser/actions) [](https://codeclimate.com/github/ammar/regexp_parser/badges)
|
|
4
4
|
|
|
5
5
|
A Ruby gem for tokenizing, parsing, and transforming regular expressions.
|
|
6
6
|
|
|
@@ -22,9 +22,6 @@ _For examples of regexp_parser in use, see [Example Projects](#example-projects)
|
|
|
22
22
|
* Ragel >= 6.0, but only if you want to build the gem or work on the scanner.
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
_Note: See the .travis.yml file for covered versions._
|
|
26
|
-
|
|
27
|
-
|
|
28
25
|
---
|
|
29
26
|
## Install
|
|
30
27
|
|
data/Rakefile
CHANGED
|
@@ -7,8 +7,8 @@ require 'bundler'
|
|
|
7
7
|
require 'rubygems/package_task'
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
RAGEL_SOURCE_DIR = File.
|
|
11
|
-
RAGEL_OUTPUT_DIR = File.
|
|
10
|
+
RAGEL_SOURCE_DIR = File.join(__dir__, 'lib/regexp_parser/scanner')
|
|
11
|
+
RAGEL_OUTPUT_DIR = File.join(__dir__, 'lib/regexp_parser')
|
|
12
12
|
RAGEL_SOURCE_FILES = %w{scanner} # scanner.rl includes property.rl
|
|
13
13
|
|
|
14
14
|
|
|
@@ -25,11 +25,11 @@ end
|
|
|
25
25
|
|
|
26
26
|
namespace :ragel do
|
|
27
27
|
desc "Process the ragel source files and output ruby code"
|
|
28
|
-
task :rb do
|
|
29
|
-
RAGEL_SOURCE_FILES.each do |
|
|
30
|
-
output_file = "#{RAGEL_OUTPUT_DIR}/#{
|
|
28
|
+
task :rb do
|
|
29
|
+
RAGEL_SOURCE_FILES.each do |source_file|
|
|
30
|
+
output_file = "#{RAGEL_OUTPUT_DIR}/#{source_file}.rb"
|
|
31
31
|
# using faster flat table driven FSM, about 25% larger code, but about 30% faster
|
|
32
|
-
sh "ragel -F1 -R #{RAGEL_SOURCE_DIR}/#{
|
|
32
|
+
sh "ragel -F1 -R #{RAGEL_SOURCE_DIR}/#{source_file}.rl -o #{output_file}"
|
|
33
33
|
|
|
34
34
|
contents = File.read(output_file)
|
|
35
35
|
|
|
@@ -42,7 +42,7 @@ namespace :ragel do
|
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
desc "Delete the ragel generated source file(s)"
|
|
45
|
-
task :clean do
|
|
45
|
+
task :clean do
|
|
46
46
|
RAGEL_SOURCE_FILES.each do |file|
|
|
47
47
|
sh "rm -f #{RAGEL_OUTPUT_DIR}/#{file}.rb"
|
|
48
48
|
end
|
|
@@ -61,7 +61,7 @@ namespace :props do
|
|
|
61
61
|
task :update do
|
|
62
62
|
require 'regexp_property_values'
|
|
63
63
|
RegexpPropertyValues.update
|
|
64
|
-
dir = File.
|
|
64
|
+
dir = File.join(__dir__, 'lib/regexp_parser/scanner/properties')
|
|
65
65
|
|
|
66
66
|
require 'psych'
|
|
67
67
|
write_hash_to_file = ->(hash, path) do
|
data/lib/regexp_parser.rb
CHANGED
|
@@ -21,7 +21,7 @@ module Regexp::Expression
|
|
|
21
21
|
self.options = options
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
def
|
|
24
|
+
def initialize_copy(orig)
|
|
25
25
|
self.text = (orig.text ? orig.text.dup : nil)
|
|
26
26
|
self.options = (orig.options ? orig.options.dup : nil)
|
|
27
27
|
self.quantifier = (orig.quantifier ? orig.quantifier.clone : nil)
|
|
@@ -34,6 +34,10 @@ module Regexp::Expression
|
|
|
34
34
|
|
|
35
35
|
alias :starts_at :ts
|
|
36
36
|
|
|
37
|
+
def base_length
|
|
38
|
+
to_s(:base).length
|
|
39
|
+
end
|
|
40
|
+
|
|
37
41
|
def full_length
|
|
38
42
|
to_s.length
|
|
39
43
|
end
|
|
@@ -118,23 +122,6 @@ module Regexp::Expression
|
|
|
118
122
|
alias :to_h :attributes
|
|
119
123
|
end
|
|
120
124
|
|
|
121
|
-
def self.parsed(exp)
|
|
122
|
-
warn('WARNING: Regexp::Expression::Base.parsed is buggy and '\
|
|
123
|
-
'will be removed in 2.0.0. Use Regexp::Parser.parse instead.')
|
|
124
|
-
case exp
|
|
125
|
-
when String
|
|
126
|
-
Regexp::Parser.parse(exp)
|
|
127
|
-
when Regexp
|
|
128
|
-
Regexp::Parser.parse(exp.source) # <- causes loss of root options
|
|
129
|
-
when Regexp::Expression # <- never triggers
|
|
130
|
-
exp
|
|
131
|
-
else
|
|
132
|
-
raise ArgumentError, 'Expression.parsed accepts a String, Regexp, or '\
|
|
133
|
-
'a Regexp::Expression as a value for exp, but it '\
|
|
134
|
-
"was given #{exp.class.name}."
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
|
|
138
125
|
end # module Regexp::Expression
|
|
139
126
|
|
|
140
127
|
require 'regexp_parser/expression/quantifier'
|
|
@@ -2,6 +2,11 @@ module Regexp::Expression
|
|
|
2
2
|
module Backreference
|
|
3
3
|
class Base < Regexp::Expression::Base
|
|
4
4
|
attr_accessor :referenced_expression
|
|
5
|
+
|
|
6
|
+
def initialize_copy(orig)
|
|
7
|
+
self.referenced_expression = orig.referenced_expression.dup
|
|
8
|
+
super
|
|
9
|
+
end
|
|
5
10
|
end
|
|
6
11
|
|
|
7
12
|
class Number < Backreference::Base
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module Regexp::Expression
|
|
2
2
|
module Conditional
|
|
3
|
-
class TooManyBranches <
|
|
3
|
+
class TooManyBranches < Regexp::Parser::Error
|
|
4
4
|
def initialize
|
|
5
5
|
super('The conditional expression has more than 2 branches')
|
|
6
6
|
end
|
|
@@ -15,6 +15,11 @@ module Regexp::Expression
|
|
|
15
15
|
ref = text.tr("'<>()", "")
|
|
16
16
|
ref =~ /\D/ ? ref : Integer(ref)
|
|
17
17
|
end
|
|
18
|
+
|
|
19
|
+
def initialize_copy(orig)
|
|
20
|
+
self.referenced_expression = orig.referenced_expression.dup
|
|
21
|
+
super
|
|
22
|
+
end
|
|
18
23
|
end
|
|
19
24
|
|
|
20
25
|
class Branch < Regexp::Expression::Sequence; end
|
|
@@ -53,6 +58,11 @@ module Regexp::Expression
|
|
|
53
58
|
def to_s(format = :full)
|
|
54
59
|
"#{text}#{condition}#{branches.join('|')})#{quantifier_affix(format)}"
|
|
55
60
|
end
|
|
61
|
+
|
|
62
|
+
def initialize_copy(orig)
|
|
63
|
+
self.referenced_expression = orig.referenced_expression.dup
|
|
64
|
+
super
|
|
65
|
+
end
|
|
56
66
|
end
|
|
57
67
|
end
|
|
58
68
|
end
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
module Regexp::Expression
|
|
2
2
|
|
|
3
3
|
class FreeSpace < Regexp::Expression::Base
|
|
4
|
-
def quantify(
|
|
5
|
-
raise
|
|
4
|
+
def quantify(_token, _text, _min = nil, _max = nil, _mode = :greedy)
|
|
5
|
+
raise Regexp::Parser::Error, 'Can not quantify a free space object'
|
|
6
6
|
end
|
|
7
7
|
end
|
|
8
8
|
|
|
@@ -10,11 +10,36 @@ module Regexp::Expression
|
|
|
10
10
|
def comment?; false end
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
class
|
|
14
|
-
|
|
13
|
+
class Passive < Group::Base
|
|
14
|
+
attr_writer :implicit
|
|
15
|
+
|
|
16
|
+
def initialize(*)
|
|
17
|
+
@implicit = false
|
|
18
|
+
super
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def to_s(format = :full)
|
|
22
|
+
if implicit?
|
|
23
|
+
"#{expressions.join}#{quantifier_affix(format)}"
|
|
24
|
+
else
|
|
25
|
+
super
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def implicit?
|
|
30
|
+
@implicit
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
15
34
|
class Absence < Group::Base; end
|
|
35
|
+
class Atomic < Group::Base; end
|
|
16
36
|
class Options < Group::Base
|
|
17
37
|
attr_accessor :option_changes
|
|
38
|
+
|
|
39
|
+
def initialize_copy(orig)
|
|
40
|
+
self.option_changes = orig.option_changes.dup
|
|
41
|
+
super
|
|
42
|
+
end
|
|
18
43
|
end
|
|
19
44
|
|
|
20
45
|
class Capture < Group::Base
|
|
@@ -33,7 +58,7 @@ module Regexp::Expression
|
|
|
33
58
|
super
|
|
34
59
|
end
|
|
35
60
|
|
|
36
|
-
def
|
|
61
|
+
def initialize_copy(orig)
|
|
37
62
|
@name = orig.name.dup
|
|
38
63
|
super
|
|
39
64
|
end
|
|
@@ -1,24 +1,12 @@
|
|
|
1
1
|
module Regexp::Expression
|
|
2
2
|
|
|
3
3
|
class Root < Regexp::Expression::Subexpression
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
unless args.first.is_a?(Regexp::Token)
|
|
7
|
-
warn('WARNING: Root.new without a Token argument is deprecated and '\
|
|
8
|
-
'will be removed in 2.0.0. Use Root.build for the old behavior.')
|
|
9
|
-
return super(self.class.build_token, *args)
|
|
10
|
-
end
|
|
11
|
-
super
|
|
4
|
+
def self.build(options = {})
|
|
5
|
+
new(build_token, options)
|
|
12
6
|
end
|
|
13
7
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
new(build_token, options)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def build_token
|
|
20
|
-
Regexp::Token.new(:expression, :root, '', 0)
|
|
21
|
-
end
|
|
8
|
+
def self.build_token
|
|
9
|
+
Regexp::Token.new(:expression, :root, '', 0)
|
|
22
10
|
end
|
|
23
11
|
end
|
|
24
12
|
end
|
|
@@ -10,7 +10,7 @@ class Regexp::MatchLength
|
|
|
10
10
|
self.exp_class = exp.class
|
|
11
11
|
self.min_rep = exp.repetitions.min
|
|
12
12
|
self.max_rep = exp.repetitions.max
|
|
13
|
-
if base = opts[:base]
|
|
13
|
+
if (base = opts[:base])
|
|
14
14
|
self.base_min = base
|
|
15
15
|
self.base_max = base
|
|
16
16
|
self.reify = ->{ '.' * base }
|
|
@@ -32,7 +32,7 @@ class Regexp::MatchLength
|
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
def endless_each
|
|
35
|
+
def endless_each
|
|
36
36
|
return enum_for(__method__) unless block_given?
|
|
37
37
|
(min..max).each { |num| yield(num) if include?(num) }
|
|
38
38
|
end
|
|
@@ -36,7 +36,7 @@ module Regexp::Expression
|
|
|
36
36
|
|
|
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
|
-
def each_expression(include_self = false
|
|
39
|
+
def each_expression(include_self = false)
|
|
40
40
|
return enum_for(__method__, include_self) unless block_given?
|
|
41
41
|
|
|
42
42
|
traverse(include_self) do |event, exp, index|
|
|
@@ -47,7 +47,7 @@ module Regexp::Expression
|
|
|
47
47
|
# Returns a new array with the results of calling the given block once
|
|
48
48
|
# for every expression. If a block is not given, returns an array with
|
|
49
49
|
# each expression and its level index as an array.
|
|
50
|
-
def flat_map(include_self = false
|
|
50
|
+
def flat_map(include_self = false)
|
|
51
51
|
result = []
|
|
52
52
|
|
|
53
53
|
each_expression(include_self) do |exp, index|
|
|
@@ -12,7 +12,7 @@ module Regexp::Expression
|
|
|
12
12
|
@max = max
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
def
|
|
15
|
+
def initialize_copy(orig)
|
|
16
16
|
@text = orig.text.dup
|
|
17
17
|
super
|
|
18
18
|
end
|
|
@@ -40,5 +40,14 @@ module Regexp::Expression
|
|
|
40
40
|
RUBY
|
|
41
41
|
end
|
|
42
42
|
alias :lazy? :reluctant?
|
|
43
|
+
|
|
44
|
+
def ==(other)
|
|
45
|
+
other.class == self.class &&
|
|
46
|
+
other.token == token &&
|
|
47
|
+
other.mode == mode &&
|
|
48
|
+
other.min == min &&
|
|
49
|
+
other.max == max
|
|
50
|
+
end
|
|
51
|
+
alias :eq :==
|
|
43
52
|
end
|
|
44
53
|
end
|