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.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +59 -0
  3. data/Gemfile +3 -3
  4. data/README.md +14 -6
  5. data/Rakefile +3 -4
  6. data/lib/regexp_parser/expression.rb +6 -43
  7. data/lib/regexp_parser/expression/classes/conditional.rb +3 -2
  8. data/lib/regexp_parser/expression/classes/escape.rb +0 -4
  9. data/lib/regexp_parser/expression/methods/match.rb +13 -0
  10. data/lib/regexp_parser/expression/methods/match_length.rb +1 -1
  11. data/lib/regexp_parser/expression/methods/options.rb +35 -0
  12. data/lib/regexp_parser/expression/methods/strfregexp.rb +0 -1
  13. data/lib/regexp_parser/expression/methods/tests.rb +6 -15
  14. data/lib/regexp_parser/expression/methods/traverse.rb +3 -1
  15. data/lib/regexp_parser/expression/sequence.rb +3 -2
  16. data/lib/regexp_parser/expression/sequence_operation.rb +2 -6
  17. data/lib/regexp_parser/lexer.rb +4 -25
  18. data/lib/regexp_parser/parser.rb +40 -33
  19. data/lib/regexp_parser/scanner.rb +1208 -1353
  20. data/lib/regexp_parser/scanner/char_type.rl +0 -3
  21. data/lib/regexp_parser/scanner/properties/long.yml +15 -1
  22. data/lib/regexp_parser/scanner/properties/short.yml +5 -0
  23. data/lib/regexp_parser/scanner/scanner.rl +116 -202
  24. data/lib/regexp_parser/syntax/tokens/unicode_property.rb +30 -0
  25. data/lib/regexp_parser/syntax/versions/2.6.2.rb +10 -0
  26. data/lib/regexp_parser/syntax/versions/2.6.3.rb +10 -0
  27. data/lib/regexp_parser/version.rb +1 -1
  28. data/spec/expression/base_spec.rb +14 -0
  29. data/spec/expression/methods/match_length_spec.rb +20 -0
  30. data/spec/expression/methods/match_spec.rb +25 -0
  31. data/spec/expression/methods/tests_spec.rb +2 -0
  32. data/spec/expression/methods/traverse_spec.rb +21 -0
  33. data/spec/expression/options_spec.rb +128 -0
  34. data/spec/expression/root_spec.rb +9 -0
  35. data/spec/expression/sequence_spec.rb +9 -0
  36. data/spec/lexer/conditionals_spec.rb +49 -119
  37. data/spec/lexer/delimiters_spec.rb +68 -0
  38. data/spec/lexer/escapes_spec.rb +8 -32
  39. data/spec/lexer/keep_spec.rb +5 -17
  40. data/spec/lexer/literals_spec.rb +73 -110
  41. data/spec/lexer/nesting_spec.rb +86 -117
  42. data/spec/lexer/refcalls_spec.rb +51 -50
  43. data/spec/parser/all_spec.rb +13 -1
  44. data/spec/parser/anchors_spec.rb +9 -23
  45. data/spec/parser/conditionals_spec.rb +9 -9
  46. data/spec/parser/errors_spec.rb +22 -43
  47. data/spec/parser/escapes_spec.rb +33 -44
  48. data/spec/parser/free_space_spec.rb +25 -4
  49. data/spec/parser/groups_spec.rb +98 -257
  50. data/spec/parser/keep_spec.rb +2 -15
  51. data/spec/parser/options_spec.rb +28 -0
  52. data/spec/parser/posix_classes_spec.rb +5 -24
  53. data/spec/parser/properties_spec.rb +42 -54
  54. data/spec/parser/quantifiers_spec.rb +42 -283
  55. data/spec/parser/refcalls_spec.rb +60 -185
  56. data/spec/parser/set/intersections_spec.rb +17 -17
  57. data/spec/parser/set/ranges_spec.rb +17 -17
  58. data/spec/parser/sets_spec.rb +5 -5
  59. data/spec/parser/types_spec.rb +11 -36
  60. data/spec/scanner/anchors_spec.rb +13 -28
  61. data/spec/scanner/conditionals_spec.rb +121 -173
  62. data/spec/scanner/delimiters_spec.rb +52 -0
  63. data/spec/scanner/errors_spec.rb +64 -87
  64. data/spec/scanner/escapes_spec.rb +53 -50
  65. data/spec/scanner/free_space_spec.rb +102 -165
  66. data/spec/scanner/groups_spec.rb +45 -64
  67. data/spec/scanner/keep_spec.rb +5 -28
  68. data/spec/scanner/literals_spec.rb +45 -81
  69. data/spec/scanner/meta_spec.rb +13 -33
  70. data/spec/scanner/options_spec.rb +36 -0
  71. data/spec/scanner/properties_spec.rb +43 -286
  72. data/spec/scanner/quantifiers_spec.rb +13 -28
  73. data/spec/scanner/refcalls_spec.rb +32 -48
  74. data/spec/scanner/sets_spec.rb +88 -102
  75. data/spec/scanner/types_spec.rb +10 -25
  76. data/spec/spec_helper.rb +1 -0
  77. data/spec/support/shared_examples.rb +77 -0
  78. data/spec/syntax/syntax_spec.rb +4 -0
  79. data/spec/syntax/versions/1.8.6_spec.rb +12 -33
  80. data/spec/syntax/versions/1.9.1_spec.rb +5 -18
  81. data/spec/syntax/versions/1.9.3_spec.rb +4 -17
  82. data/spec/syntax/versions/2.0.0_spec.rb +8 -23
  83. data/spec/syntax/versions/2.2.0_spec.rb +4 -17
  84. data/spec/syntax/versions/aliases_spec.rb +27 -109
  85. metadata +28 -10
  86. data/spec/scanner/scripts_spec.rb +0 -49
  87. data/spec/scanner/unicode_blocks_spec.rb +0 -28
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 707834a32bc2295b448953730eabddabb11bafc68fdf3148174f7be61d8b1f30
4
- data.tar.gz: 72d199d28c342d6aae178a5876a7df6f59abcdf40c6ac4f05ea9dc40d16d9f3a
3
+ metadata.gz: 9c8e3ba5269d32f57fdcad4ba98f16bc88b74713106a23f63ba2728fa89cf802
4
+ data.tar.gz: bbb1fe8c3f72b750a707a9f6c237c752455b4cd34d2bc8b0f255284fd32d4ed3
5
5
  SHA512:
6
- metadata.gz: 4c1402afedc1efb79f633ee93065598b64732519ba587ca3f682eb8bbb4aaa264e31dd916b95f9751f7c6e85e867efa260501b40e55409327efa5b769346a183
7
- data.tar.gz: 6335cbc411b08adb64bfca9646eebc3a5c39d4651a2495d34f87fca21927da3a363fc320159a3732cdd9e2d8732986190fcd6c9d523b7308531f91848951ccbd
6
+ metadata.gz: 93f94773ee6cb173771608ecdaf67e9e444e1ba7922cd97b8124a6ec90868e94b484ad6bdd0599d9ae9c2247e2a1627cdb03c620ce85f62d320ba8b1fdbb63bb
7
+ data.tar.gz: 9e1927e7c10d182bce099f24964f8c7e88ac76d479d22c632ab09406bc37711c9cc78af53892d46b009d0f12c8c3ffcd2221b2a1b2ca5365b3d3c1797448f3f2
@@ -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
@@ -3,7 +3,7 @@ source 'https://rubygems.org'
3
3
  gemspec
4
4
 
5
5
  group :development, :test do
6
- gem 'rake'
7
- gem 'regexp_property_values'
8
- gem 'rspec'
6
+ gem 'rake', '~> 13.0'
7
+ gem 'regexp_property_values', '~> 1.0'
8
+ gem 'rspec', '~> 3.8'
9
9
  end
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 1.9, 2.x, and JRuby (1.9 mode) runtimes.
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. The scanner does not support such
140
- implementation quirks.
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
- _, long_names = RegexpPropertyValues.short_and_long_names
78
- long_names_to_tokens = long_names.map do |name|
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.downcase.gsub(/[^0-9a-z=.]/, ''), v.downcase]
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
- Branch.add_to(self, { conditional_level: conditional_level + 1 })
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
 
@@ -60,10 +60,6 @@ module Regexp::Expression
60
60
  codepoint.chr('utf-8')
61
61
  end
62
62
 
63
- def codepoint
64
- raise NotImplementedError, 'implement in subclass'
65
- end
66
-
67
63
  private
68
64
 
69
65
  def control_sequence_to_s(control_sequence)
@@ -0,0 +1,13 @@
1
+ module Regexp::Expression
2
+ class Base
3
+ def match?(string)
4
+ !!match(string)
5
+ end
6
+ alias :matches? :match?
7
+
8
+ def match(string, offset = 0)
9
+ Regexp.new(to_s).match(string, offset)
10
+ end
11
+ alias :=~ :match
12
+ end
13
+ end
@@ -22,7 +22,7 @@ class Regexp::MatchLength
22
22
  end
23
23
 
24
24
  def each(opts = {})
25
- return enum_for(__method__) unless block_given?
25
+ return enum_for(__method__, opts) unless block_given?
26
26
  limit = opts[:limit] || 1000
27
27
  yielded = 0
28
28
  (min..max).each do |num|
@@ -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
@@ -1,5 +1,4 @@
1
1
  module Regexp::Expression
2
-
3
2
  class Base
4
3
 
5
4
  # %l Level (depth) of the expression. Returns 'root' for the root
@@ -75,32 +75,23 @@ module Regexp::Expression
75
75
  def one_of?(scope, top = true)
76
76
  case scope
77
77
  when Array
78
- if scope.include?(:*)
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
- return one_of?(scope[test_type], false)
83
+ one_of?(scope[test_type], false)
88
84
  else
89
- return (scope.has_key?(type) and one_of?(scope[type], false))
85
+ scope.has_key?(type) && one_of?(scope[type], false)
90
86
  end
91
87
 
92
88
  when Symbol
93
- return true if scope == :*
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 "Array, Hash, or Symbol expected, #{scope.class.name} given"
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
- raise 'traverse requires a block' unless block_given?
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, options = {})
21
+ def add_to(subexpression, params = {}, active_opts = {})
22
22
  sequence = at_levels(
23
23
  subexpression.level,
24
24
  subexpression.set_level,
25
- options[:conditional_level] || subexpression.conditional_level
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)
@@ -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,