regexp_parser 1.3.0 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (169) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +53 -1
  3. data/Gemfile +3 -3
  4. data/README.md +10 -14
  5. data/Rakefile +3 -4
  6. data/lib/regexp_parser/expression.rb +28 -53
  7. data/lib/regexp_parser/expression/classes/backref.rb +18 -10
  8. data/lib/regexp_parser/expression/classes/conditional.rb +7 -2
  9. data/lib/regexp_parser/expression/classes/escape.rb +0 -4
  10. data/lib/regexp_parser/expression/classes/group.rb +4 -2
  11. data/lib/regexp_parser/expression/classes/keep.rb +1 -3
  12. data/lib/regexp_parser/expression/methods/match.rb +13 -0
  13. data/lib/regexp_parser/expression/methods/match_length.rb +172 -0
  14. data/lib/regexp_parser/expression/methods/options.rb +35 -0
  15. data/lib/regexp_parser/expression/methods/strfregexp.rb +0 -1
  16. data/lib/regexp_parser/expression/methods/tests.rb +6 -15
  17. data/lib/regexp_parser/expression/quantifier.rb +2 -2
  18. data/lib/regexp_parser/expression/sequence.rb +3 -6
  19. data/lib/regexp_parser/expression/sequence_operation.rb +2 -6
  20. data/lib/regexp_parser/expression/subexpression.rb +3 -5
  21. data/lib/regexp_parser/lexer.rb +30 -44
  22. data/lib/regexp_parser/parser.rb +47 -24
  23. data/lib/regexp_parser/scanner.rb +1159 -1329
  24. data/lib/regexp_parser/scanner/char_type.rl +0 -3
  25. data/lib/regexp_parser/scanner/properties/long.yml +34 -1
  26. data/lib/regexp_parser/scanner/properties/short.yml +12 -0
  27. data/lib/regexp_parser/scanner/scanner.rl +82 -190
  28. data/lib/regexp_parser/syntax/tokens.rb +2 -10
  29. data/lib/regexp_parser/syntax/tokens/unicode_property.rb +72 -21
  30. data/lib/regexp_parser/syntax/versions/2.6.0.rb +10 -0
  31. data/lib/regexp_parser/syntax/versions/2.6.2.rb +10 -0
  32. data/lib/regexp_parser/syntax/versions/2.6.3.rb +10 -0
  33. data/lib/regexp_parser/version.rb +1 -1
  34. data/regexp_parser.gemspec +3 -3
  35. data/spec/expression/base_spec.rb +94 -0
  36. data/spec/expression/clone_spec.rb +120 -0
  37. data/spec/expression/conditional_spec.rb +89 -0
  38. data/spec/expression/free_space_spec.rb +27 -0
  39. data/spec/expression/methods/match_length_spec.rb +154 -0
  40. data/spec/expression/methods/match_spec.rb +25 -0
  41. data/spec/expression/methods/strfregexp_spec.rb +224 -0
  42. data/spec/expression/methods/tests_spec.rb +99 -0
  43. data/spec/expression/methods/traverse_spec.rb +140 -0
  44. data/spec/expression/options_spec.rb +128 -0
  45. data/spec/expression/root_spec.rb +9 -0
  46. data/spec/expression/sequence_spec.rb +9 -0
  47. data/spec/expression/subexpression_spec.rb +50 -0
  48. data/spec/expression/to_h_spec.rb +26 -0
  49. data/spec/expression/to_s_spec.rb +100 -0
  50. data/spec/lexer/all_spec.rb +22 -0
  51. data/spec/lexer/conditionals_spec.rb +53 -0
  52. data/spec/lexer/escapes_spec.rb +14 -0
  53. data/spec/lexer/keep_spec.rb +10 -0
  54. data/spec/lexer/literals_spec.rb +89 -0
  55. data/spec/lexer/nesting_spec.rb +99 -0
  56. data/spec/lexer/refcalls_spec.rb +55 -0
  57. data/spec/parser/all_spec.rb +43 -0
  58. data/spec/parser/alternation_spec.rb +88 -0
  59. data/spec/parser/anchors_spec.rb +17 -0
  60. data/spec/parser/conditionals_spec.rb +179 -0
  61. data/spec/parser/errors_spec.rb +30 -0
  62. data/spec/parser/escapes_spec.rb +121 -0
  63. data/spec/parser/free_space_spec.rb +130 -0
  64. data/spec/parser/groups_spec.rb +108 -0
  65. data/spec/parser/keep_spec.rb +6 -0
  66. data/spec/parser/posix_classes_spec.rb +8 -0
  67. data/spec/parser/properties_spec.rb +115 -0
  68. data/spec/parser/quantifiers_spec.rb +51 -0
  69. data/spec/parser/refcalls_spec.rb +112 -0
  70. data/spec/parser/set/intersections_spec.rb +127 -0
  71. data/spec/parser/set/ranges_spec.rb +111 -0
  72. data/spec/parser/sets_spec.rb +178 -0
  73. data/spec/parser/types_spec.rb +18 -0
  74. data/spec/scanner/all_spec.rb +18 -0
  75. data/spec/scanner/anchors_spec.rb +21 -0
  76. data/spec/scanner/conditionals_spec.rb +128 -0
  77. data/spec/scanner/errors_spec.rb +68 -0
  78. data/spec/scanner/escapes_spec.rb +53 -0
  79. data/spec/scanner/free_space_spec.rb +133 -0
  80. data/spec/scanner/groups_spec.rb +52 -0
  81. data/spec/scanner/keep_spec.rb +10 -0
  82. data/spec/scanner/literals_spec.rb +49 -0
  83. data/spec/scanner/meta_spec.rb +18 -0
  84. data/spec/scanner/properties_spec.rb +64 -0
  85. data/spec/scanner/quantifiers_spec.rb +20 -0
  86. data/spec/scanner/refcalls_spec.rb +36 -0
  87. data/spec/scanner/sets_spec.rb +102 -0
  88. data/spec/scanner/types_spec.rb +14 -0
  89. data/spec/spec_helper.rb +15 -0
  90. data/{test → spec}/support/runner.rb +9 -8
  91. data/spec/support/shared_examples.rb +77 -0
  92. data/{test → spec}/support/warning_extractor.rb +5 -7
  93. data/spec/syntax/syntax_spec.rb +48 -0
  94. data/spec/syntax/syntax_token_map_spec.rb +23 -0
  95. data/spec/syntax/versions/1.8.6_spec.rb +17 -0
  96. data/spec/syntax/versions/1.9.1_spec.rb +10 -0
  97. data/spec/syntax/versions/1.9.3_spec.rb +9 -0
  98. data/spec/syntax/versions/2.0.0_spec.rb +13 -0
  99. data/spec/syntax/versions/2.2.0_spec.rb +9 -0
  100. data/spec/syntax/versions/aliases_spec.rb +37 -0
  101. data/spec/token/token_spec.rb +85 -0
  102. metadata +144 -143
  103. data/test/expression/test_all.rb +0 -12
  104. data/test/expression/test_base.rb +0 -90
  105. data/test/expression/test_clone.rb +0 -89
  106. data/test/expression/test_conditionals.rb +0 -113
  107. data/test/expression/test_free_space.rb +0 -35
  108. data/test/expression/test_set.rb +0 -84
  109. data/test/expression/test_strfregexp.rb +0 -230
  110. data/test/expression/test_subexpression.rb +0 -58
  111. data/test/expression/test_tests.rb +0 -99
  112. data/test/expression/test_to_h.rb +0 -59
  113. data/test/expression/test_to_s.rb +0 -104
  114. data/test/expression/test_traverse.rb +0 -161
  115. data/test/helpers.rb +0 -10
  116. data/test/lexer/test_all.rb +0 -41
  117. data/test/lexer/test_conditionals.rb +0 -127
  118. data/test/lexer/test_keep.rb +0 -24
  119. data/test/lexer/test_literals.rb +0 -130
  120. data/test/lexer/test_nesting.rb +0 -132
  121. data/test/lexer/test_refcalls.rb +0 -56
  122. data/test/parser/set/test_intersections.rb +0 -127
  123. data/test/parser/set/test_ranges.rb +0 -111
  124. data/test/parser/test_all.rb +0 -64
  125. data/test/parser/test_alternation.rb +0 -92
  126. data/test/parser/test_anchors.rb +0 -34
  127. data/test/parser/test_conditionals.rb +0 -187
  128. data/test/parser/test_errors.rb +0 -63
  129. data/test/parser/test_escapes.rb +0 -134
  130. data/test/parser/test_free_space.rb +0 -139
  131. data/test/parser/test_groups.rb +0 -289
  132. data/test/parser/test_keep.rb +0 -21
  133. data/test/parser/test_posix_classes.rb +0 -27
  134. data/test/parser/test_properties.rb +0 -133
  135. data/test/parser/test_quantifiers.rb +0 -301
  136. data/test/parser/test_refcalls.rb +0 -186
  137. data/test/parser/test_sets.rb +0 -179
  138. data/test/parser/test_types.rb +0 -50
  139. data/test/scanner/test_all.rb +0 -38
  140. data/test/scanner/test_anchors.rb +0 -38
  141. data/test/scanner/test_conditionals.rb +0 -184
  142. data/test/scanner/test_errors.rb +0 -91
  143. data/test/scanner/test_escapes.rb +0 -56
  144. data/test/scanner/test_free_space.rb +0 -200
  145. data/test/scanner/test_groups.rb +0 -79
  146. data/test/scanner/test_keep.rb +0 -35
  147. data/test/scanner/test_literals.rb +0 -89
  148. data/test/scanner/test_meta.rb +0 -40
  149. data/test/scanner/test_properties.rb +0 -312
  150. data/test/scanner/test_quantifiers.rb +0 -37
  151. data/test/scanner/test_refcalls.rb +0 -52
  152. data/test/scanner/test_scripts.rb +0 -53
  153. data/test/scanner/test_sets.rb +0 -119
  154. data/test/scanner/test_types.rb +0 -35
  155. data/test/scanner/test_unicode_blocks.rb +0 -30
  156. data/test/support/disable_autotest.rb +0 -8
  157. data/test/syntax/test_all.rb +0 -6
  158. data/test/syntax/test_syntax.rb +0 -61
  159. data/test/syntax/test_syntax_token_map.rb +0 -25
  160. data/test/syntax/versions/test_1.8.rb +0 -55
  161. data/test/syntax/versions/test_1.9.1.rb +0 -36
  162. data/test/syntax/versions/test_1.9.3.rb +0 -32
  163. data/test/syntax/versions/test_2.0.0.rb +0 -37
  164. data/test/syntax/versions/test_2.2.0.rb +0 -32
  165. data/test/syntax/versions/test_aliases.rb +0 -129
  166. data/test/syntax/versions/test_all.rb +0 -5
  167. data/test/test_all.rb +0 -5
  168. data/test/token/test_all.rb +0 -2
  169. data/test/token/test_token.rb +0 -107
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9af74355b57139b93d0207bfbf6fc6fbb43c1eb6aa531bd11710e39168af107a
4
- data.tar.gz: 8d63533aa2206b121fd59959a43cad2b64e3b3c6d0f8617953d2c401033c86d5
3
+ metadata.gz: 0e084510a97816730f68028cba8be7b9ee576e886347952d8400cd26293f3361
4
+ data.tar.gz: f98f2bbb3558c6a50d3415c830ba6dae1f09b2aca944f411b88c1cd65d527f60
5
5
  SHA512:
6
- metadata.gz: de6afb1888075eaa8d220192882494eb67c54aaba5fa84b991adf753dbb06949b8b0ea6d44054d32c3cba1e8cb6ee04d8f8f2f8643e4663188ddca3b7ec7e07a
7
- data.tar.gz: f9e7d91a317bb153b645380a6447faca2656b87fa164afae9dc1cf9bc63463c11a87388258d18a49ed3df7afc3a7b25cd0a2113db412c2e7f504cee9aec8c255
6
+ metadata.gz: 972c429ea4b47e2d2fefbc087cb23362f3e385cbbdbbead8013537d9bfe12b07237dcb1dcfaab6e1793037347d310702fa7fc035ab874dc24722b041493cc3f2
7
+ data.tar.gz: 6ace6c2390101f9d95bcc9325ba70c4d4d9d90d5796ab015ffcef1f58b907eb3a2649ee07f3f77e6f2682a2f4803e6f94e634855e39a97480a1fb17f00b97c23
@@ -1,5 +1,57 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ### [1.6.0] - 2019-06-16 - [Janosch Müller](mailto:janosch84@gmail.com)
4
+
5
+ ### Added
6
+
7
+ - Added support for 16 new unicode properties introduced in Ruby 2.6.2 and 2.6.3
8
+
9
+ ### [1.5.1] - 2019-05-23 - [Janosch Müller](mailto:janosch84@gmail.com)
10
+
11
+ ### Fixed
12
+
13
+ - Fixed `#options` (and thus `#i?`, `#u?` etc.) not being set for some expressions:
14
+ * this affected posix classes as well as alternation, conditional, and intersection branches
15
+ * `#options` was already correct for all child expressions of such branches
16
+ * this only made an operational difference for posix classes as they respect encoding flags
17
+ - Fixed `#options` not respecting all negative options in weird cases like '(?u-m-x)'
18
+ - Fixed `Group#option_changes` not accounting for indirectly disabled (overridden) encoding flags
19
+ - Fixed `Scanner` allowing negative encoding options if there were no positive options, e.g. '(?-u)'
20
+ - Fixed `ScannerError` for some valid meta/control sequences such as '\\C-\\\\'
21
+ - Fixed `Expression#match` and `#=~` not working with a single argument
22
+
23
+ ### [1.5.0] - 2019-05-14 - [Janosch Müller](mailto:janosch84@gmail.com)
24
+
25
+ ### Added
26
+
27
+ - Added `#referenced_expression` for backrefs, subexp calls and conditionals
28
+ * returns the `Group` expression that is being referenced via name or number
29
+ - Added `Expression#repetitions`
30
+ * returns a `Range` of allowed repetitions (`1..1` if there is no quantifier)
31
+ * like `#quantity` but with a more uniform interface
32
+ - Added `Expression#match_length`
33
+ * allows to inspect and iterate over String lengths matched by the Expression
34
+
35
+ ### Fixed
36
+
37
+ - Fixed `Expression#clone` "direction"
38
+ * it used to dup ivars onto the callee, leaving only the clone referencing the original objects
39
+ * this will affect you if you call `#eql?`/`#equal?` on expressions or use them as Hash keys
40
+ - Fixed `#clone` results for `Sequences`, e.g. alternations and conditionals
41
+ * the inner `#text` was cloned onto the `Sequence` and thus duplicated
42
+ * e.g. `Regexp::Parser.parse(/(a|bc)/).clone.to_s # => (aa|bcbc)`
43
+ - Fixed inconsistent `#to_s` output for `Sequences`
44
+ * it used to return only the "specific" text, e.g. "|" for an alternation
45
+ * now it includes nested expressions as it does for all other `Subexpressions`
46
+ - Fixed quantification of codepoint lists with more than one entry (`\u{62 63 64}+`)
47
+ * quantifiers apply only to the last entry, so this token is now split up if quantified
48
+
49
+ ### [1.4.0] - 2019-04-02 - [Janosch Müller](mailto:janosch84@gmail.com)
50
+
51
+ ### Added
52
+
53
+ - Added support for 19 new unicode properties introduced in Ruby 2.6.0
54
+
3
55
  ### [1.3.0] - 2018-11-14 - [Janosch Müller](mailto:janosch84@gmail.com)
4
56
 
5
57
  ### Added
@@ -69,7 +121,7 @@ This release includes several breaking changes, mostly to character sets, #map a
69
121
  - Changed `(?m)` and the likes to emit as `:options_switch` token (@4ade4d1)
70
122
  * allows differentiating from group-local `:options`, e.g. `(?m:.)`
71
123
  - Changed name of `Backreference::..NestLevel` to `..RecursionLevel` (@4184339)
72
- - Changed B`ackreference::Number#number` from `String` to `Integer` (@40a2231)
124
+ - Changed `Backreference::Number#number` from `String` to `Integer` (@40a2231)
73
125
 
74
126
  ### Added
75
127
 
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 'test-unit'
6
+ gem 'rake', '~> 12.2'
7
+ gem 'regexp_property_values', '~> 1.0'
8
+ gem 'rspec', '~> 3.8'
9
9
  end
data/README.md CHANGED
@@ -357,7 +357,7 @@ _Note that not all of these are available in all versions of Ruby_
357
357
  |   _**Meta**_ | `\M-c`, `\M-\C-C`, `\M-\cC`, `\C-\M-C`, `\c\M-C` | ✓ |
358
358
  |   _**Octal**_ | `\0`, `\01`, `\012` | ✓ |
359
359
  |   _**Unicode**_ | `\uHHHH`, `\u{H+ H+}` | ✓ |
360
- | **Unicode Properties** | _<sub>([Unicode 10.0.0](http://www.unicode.org/versions/Unicode10.0.0/))</sub>_ | &#x22f1; |
360
+ | **Unicode Properties** | _<sub>([Unicode 11.0.0](http://www.unicode.org/versions/Unicode11.0.0/))</sub>_ | &#x22f1; |
361
361
  | &emsp;&nbsp;_**Age**_ | `\p{Age=5.2}`, `\P{age=7.0}`, `\p{^age=8.0}` | &#x2713; |
362
362
  | &emsp;&nbsp;_**Blocks**_ | `\p{InArmenian}`, `\P{InKhmer}`, `\p{^InThai}` | &#x2713; |
363
363
  | &emsp;&nbsp;_**Classes**_ | `\p{Alpha}`, `\P{Space}`, `\p{^Alnum}` | &#x2713; |
@@ -391,28 +391,22 @@ To run the tests simply run rake from the root directory, as 'test' is the defau
391
391
 
392
392
  It generates the scanner's code from the Ragel source files and runs all the tests, thus it requires Ragel to be installed.
393
393
 
394
- The tests use Ruby's test/unit. They can also be run with:
394
+ The tests use RSpec. They can also be run with the test runner that whitelists some warnings:
395
395
 
396
396
  ```
397
397
  bin/test
398
398
  ```
399
399
 
400
- The test runner accepts all arguments accepted by test/unit. You can run a specific test like so:
400
+ You can run a specific test like so:
401
401
 
402
402
  ```
403
- bin/test test/scanner/test_properties.rb
403
+ bin/test spec/scanner/properties_spec.rb
404
404
  ```
405
405
 
406
- It is sometimes helpful during development to focus on a specific test case, for example:
406
+ Note that changes to Ragel files will not be reflected when running `rspec` or `bin/test`, so you might want to run:
407
407
 
408
408
  ```
409
- bin/test test/expression/test_base.rb -n test_expression_to_re
410
- ```
411
-
412
- Note that changes to Ragel files will not be reflected when using `bin/test`, so you might want to run:
413
-
414
- ```
415
- rake ragel:rb && bin/test test/scanner/test_properties.rb
409
+ rake ragel:rb && bin/test spec/scanner/properties_spec.rb
416
410
  ```
417
411
 
418
412
  ## Building
@@ -440,7 +434,9 @@ Projects using regexp_parser.
440
434
 
441
435
  - [meta_re](https://github.com/ammar/meta_re) is a regular expression preprocessor with alias support.
442
436
 
443
- - [mutant](https://github.com/mbj/mutant) manipulates your regular expressions (amongst others) to see if your tests cover their behavior.
437
+ - [mutant](https://github.com/mbj/mutant) (before v0.9.0) manipulates your regular expressions (amongst others) to see if your tests cover their behavior.
438
+
439
+ - [twitter-cldr-rb](https://github.com/twitter/twitter-cldr-rb) uses regexp_parser to generate examples of postal codes.
444
440
 
445
441
  - [js_regex](https://github.com/janosch-x/js_regex) converts Ruby regular expressions to JavaScript-compatible regular expressions.
446
442
 
@@ -471,4 +467,4 @@ Documentation and books used while working on this project.
471
467
 
472
468
  ---
473
469
  ##### Copyright
474
- _Copyright (c) 2010-2016 Ammar Ali. See LICENSE file for details._
470
+ _Copyright (c) 2010-2019 Ammar Ali. See LICENSE file for details._
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
@@ -21,10 +21,10 @@ module Regexp::Expression
21
21
  self.options = options
22
22
  end
23
23
 
24
- def initialize_clone(other)
25
- other.text = (text ? text.dup : nil)
26
- other.options = (options ? options.dup : nil)
27
- other.quantifier = (quantifier ? quantifier.clone : nil)
24
+ def initialize_clone(orig)
25
+ self.text = (orig.text ? orig.text.dup : nil)
26
+ self.options = (orig.options ? orig.options.dup : nil)
27
+ self.quantifier = (orig.quantifier ? orig.quantifier.clone : nil)
28
28
  super
29
29
  end
30
30
 
@@ -62,15 +62,28 @@ module Regexp::Expression
62
62
  self.quantifier = Quantifier.new(token, text, min, max, mode)
63
63
  end
64
64
 
65
+ def unquantified_clone
66
+ clone.tap { |exp| exp.quantifier = nil }
67
+ end
68
+
65
69
  def quantified?
66
70
  !quantifier.nil?
67
71
  end
68
72
 
73
+ # Deprecated. Prefer `#repetitions` which has a more uniform interface.
69
74
  def quantity
70
75
  return [nil,nil] unless quantified?
71
76
  [quantifier.min, quantifier.max]
72
77
  end
73
78
 
79
+ def repetitions
80
+ return 1..1 unless quantified?
81
+ min = quantifier.min
82
+ max = quantifier.max < 0 ? Float::INFINITY : quantifier.max
83
+ # fix Range#minmax - https://bugs.ruby-lang.org/issues/15807
84
+ (min..max).tap { |r| r.define_singleton_method(:minmax) { [min, max] } }
85
+ end
86
+
74
87
  def greedy?
75
88
  quantified? and quantifier.greedy?
76
89
  end
@@ -84,49 +97,6 @@ module Regexp::Expression
84
97
  quantified? and quantifier.possessive?
85
98
  end
86
99
 
87
- def multiline?
88
- options[:m] == true
89
- end
90
- alias :m? :multiline?
91
-
92
- def case_insensitive?
93
- options[:i] == true
94
- end
95
- alias :i? :case_insensitive?
96
- alias :ignore_case? :case_insensitive?
97
-
98
- def free_spacing?
99
- options[:x] == true
100
- end
101
- alias :x? :free_spacing?
102
- alias :extended? :free_spacing?
103
-
104
- if RUBY_VERSION >= '2.0'
105
- def default_classes?
106
- options[:d] == true
107
- end
108
- alias :d? :default_classes?
109
-
110
- def ascii_classes?
111
- options[:a] == true
112
- end
113
- alias :a? :ascii_classes?
114
-
115
- def unicode_classes?
116
- options[:u] == true
117
- end
118
- alias :u? :unicode_classes?
119
- end
120
-
121
- def matches?(string)
122
- Regexp.new(to_s) =~ string ? true : false
123
- end
124
-
125
- def match(string, offset)
126
- Regexp.new(to_s).match(string, offset)
127
- end
128
- alias :=~ :match
129
-
130
100
  def attributes
131
101
  {
132
102
  type: type,
@@ -145,12 +115,14 @@ module Regexp::Expression
145
115
  end
146
116
 
147
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.')
148
120
  case exp
149
121
  when String
150
122
  Regexp::Parser.parse(exp)
151
123
  when Regexp
152
- Regexp::Parser.parse(exp.source)
153
- when Regexp::Expression
124
+ Regexp::Parser.parse(exp.source) # <- causes loss of root options
125
+ when Regexp::Expression # <- never triggers
154
126
  exp
155
127
  else
156
128
  raise ArgumentError, 'Expression.parsed accepts a String, Regexp, or '\
@@ -161,10 +133,6 @@ module Regexp::Expression
161
133
 
162
134
  end # module Regexp::Expression
163
135
 
164
- require 'regexp_parser/expression/methods/tests'
165
- require 'regexp_parser/expression/methods/traverse'
166
- require 'regexp_parser/expression/methods/strfregexp'
167
-
168
136
  require 'regexp_parser/expression/quantifier'
169
137
  require 'regexp_parser/expression/subexpression'
170
138
  require 'regexp_parser/expression/sequence'
@@ -186,3 +154,10 @@ require 'regexp_parser/expression/classes/set'
186
154
  require 'regexp_parser/expression/classes/set/intersection'
187
155
  require 'regexp_parser/expression/classes/set/range'
188
156
  require 'regexp_parser/expression/classes/type'
157
+
158
+ require 'regexp_parser/expression/methods/match'
159
+ require 'regexp_parser/expression/methods/match_length'
160
+ require 'regexp_parser/expression/methods/options'
161
+ require 'regexp_parser/expression/methods/strfregexp'
162
+ require 'regexp_parser/expression/methods/tests'
163
+ require 'regexp_parser/expression/methods/traverse'
@@ -1,9 +1,12 @@
1
1
  module Regexp::Expression
2
2
  module Backreference
3
- class Base < Regexp::Expression::Base; end
3
+ class Base < Regexp::Expression::Base
4
+ attr_accessor :referenced_expression
5
+ end
4
6
 
5
7
  class Number < Backreference::Base
6
8
  attr_reader :number
9
+ alias reference number
7
10
 
8
11
  def initialize(token, options = {})
9
12
  @number = token.text[token.token.equal?(:number) ? 1..-1 : 3..-2].to_i
@@ -13,6 +16,7 @@ module Regexp::Expression
13
16
 
14
17
  class Name < Backreference::Base
15
18
  attr_reader :name
19
+ alias reference name
16
20
 
17
21
  def initialize(token, options = {})
18
22
  @name = token.text[3..-2]
@@ -20,27 +24,31 @@ module Regexp::Expression
20
24
  end
21
25
  end
22
26
 
27
+ class NumberRelative < Backreference::Number
28
+ attr_accessor :effective_number
29
+ alias reference effective_number
30
+ end
31
+
23
32
  class NumberCall < Backreference::Number; end
24
- class NumberRelative < Backreference::Number; end
25
- class NumberCallRelative < Backreference::Number; end
26
- class NameCall < Backreference::Name; end
33
+ class NameCall < Backreference::Name; end
34
+ class NumberCallRelative < Backreference::NumberRelative; end
27
35
 
28
- class NumberRecursionLevel < Backreference::Base
29
- attr_reader :number, :recursion_level
36
+ class NumberRecursionLevel < Backreference::Number
37
+ attr_reader :recursion_level
30
38
 
31
39
  def initialize(token, options = {})
32
- @number, @recursion_level = token.text[3..-2].split(/(?=[+-])/).map(&:to_i)
33
40
  super
41
+ @number, @recursion_level = token.text[3..-2].split(/(?=[+-])/).map(&:to_i)
34
42
  end
35
43
  end
36
44
 
37
- class NameRecursionLevel < Backreference::Base
38
- attr_reader :name, :recursion_level
45
+ class NameRecursionLevel < Backreference::Name
46
+ attr_reader :recursion_level
39
47
 
40
48
  def initialize(token, options = {})
49
+ super
41
50
  @name, recursion_level = token.text[3..-2].split(/(?=[+-])/)
42
51
  @recursion_level = recursion_level.to_i
43
- super
44
52
  end
45
53
  end
46
54
  end
@@ -7,6 +7,8 @@ module Regexp::Expression
7
7
  end
8
8
 
9
9
  class Condition < Regexp::Expression::Base
10
+ attr_accessor :referenced_expression
11
+
10
12
  # Name or number of the referenced capturing group that determines state.
11
13
  # Returns a String if reference is by name, Integer if by number.
12
14
  def reference
@@ -18,13 +20,16 @@ module Regexp::Expression
18
20
  class Branch < Regexp::Expression::Sequence; end
19
21
 
20
22
  class Expression < Regexp::Expression::Subexpression
23
+ attr_accessor :referenced_expression
24
+
21
25
  def <<(exp)
22
26
  expressions.last << exp
23
27
  end
24
28
 
25
- def add_sequence
29
+ def add_sequence(active_opts = {})
26
30
  raise TooManyBranches.new if branches.length == 2
27
- Branch.add_to(self, { conditional_level: conditional_level + 1 })
31
+ params = { conditional_level: conditional_level + 1 }
32
+ Branch.add_to(self, params, active_opts)
28
33
  end
29
34
  alias :branch :add_sequence
30
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)
@@ -19,20 +19,22 @@ module Regexp::Expression
19
19
 
20
20
  class Capture < Group::Base
21
21
  attr_accessor :number, :number_at_level
22
+ alias identifier number
22
23
 
23
24
  def capturing?; true end
24
25
  end
25
26
 
26
27
  class Named < Group::Capture
27
28
  attr_reader :name
29
+ alias identifier name
28
30
 
29
31
  def initialize(token, options = {})
30
32
  @name = token.text[3..-2]
31
33
  super
32
34
  end
33
35
 
34
- def initialize_clone(other)
35
- other.instance_variable_set(:@name, name.dup)
36
+ def initialize_clone(orig)
37
+ @name = orig.name.dup
36
38
  super
37
39
  end
38
40
  end
@@ -1,7 +1,5 @@
1
1
  module Regexp::Expression
2
-
3
2
  module Keep
4
- class Mark < Regexp::Expression::Base; end
3
+ class Mark < Regexp::Expression::Base; end
5
4
  end
6
-
7
5
  end
@@ -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