regexp_parser 1.7.0 → 2.9.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 (166) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +9 -3
  3. data/LICENSE +1 -1
  4. data/Rakefile +6 -70
  5. data/lib/regexp_parser/error.rb +4 -0
  6. data/lib/regexp_parser/expression/base.rb +76 -0
  7. data/lib/regexp_parser/expression/classes/alternation.rb +1 -1
  8. data/lib/regexp_parser/expression/classes/anchor.rb +0 -2
  9. data/lib/regexp_parser/expression/classes/{backref.rb → backreference.rb} +22 -2
  10. data/lib/regexp_parser/expression/classes/{set → character_set}/range.rb +4 -8
  11. data/lib/regexp_parser/expression/classes/{set.rb → character_set.rb} +4 -8
  12. data/lib/regexp_parser/expression/classes/{type.rb → character_type.rb} +0 -2
  13. data/lib/regexp_parser/expression/classes/conditional.rb +11 -5
  14. data/lib/regexp_parser/expression/classes/{escape.rb → escape_sequence.rb} +15 -7
  15. data/lib/regexp_parser/expression/classes/free_space.rb +5 -5
  16. data/lib/regexp_parser/expression/classes/group.rb +28 -15
  17. data/lib/regexp_parser/expression/classes/keep.rb +2 -0
  18. data/lib/regexp_parser/expression/classes/literal.rb +1 -5
  19. data/lib/regexp_parser/expression/classes/posix_class.rb +5 -5
  20. data/lib/regexp_parser/expression/classes/root.rb +4 -19
  21. data/lib/regexp_parser/expression/classes/{property.rb → unicode_property.rb} +11 -12
  22. data/lib/regexp_parser/expression/methods/construct.rb +41 -0
  23. data/lib/regexp_parser/expression/methods/human_name.rb +43 -0
  24. data/lib/regexp_parser/expression/methods/match_length.rb +11 -7
  25. data/lib/regexp_parser/expression/methods/negative.rb +20 -0
  26. data/lib/regexp_parser/expression/methods/parts.rb +23 -0
  27. data/lib/regexp_parser/expression/methods/printing.rb +26 -0
  28. data/lib/regexp_parser/expression/methods/strfregexp.rb +1 -1
  29. data/lib/regexp_parser/expression/methods/tests.rb +47 -1
  30. data/lib/regexp_parser/expression/methods/traverse.rb +34 -18
  31. data/lib/regexp_parser/expression/quantifier.rb +57 -17
  32. data/lib/regexp_parser/expression/sequence.rb +11 -47
  33. data/lib/regexp_parser/expression/sequence_operation.rb +4 -9
  34. data/lib/regexp_parser/expression/shared.rb +111 -0
  35. data/lib/regexp_parser/expression/subexpression.rb +27 -19
  36. data/lib/regexp_parser/expression.rb +15 -141
  37. data/lib/regexp_parser/lexer.rb +83 -41
  38. data/lib/regexp_parser/parser.rb +372 -429
  39. data/lib/regexp_parser/scanner/char_type.rl +11 -11
  40. data/lib/regexp_parser/scanner/errors/premature_end_error.rb +8 -0
  41. data/lib/regexp_parser/scanner/errors/scanner_error.rb +6 -0
  42. data/lib/regexp_parser/scanner/errors/validation_error.rb +63 -0
  43. data/lib/regexp_parser/scanner/properties/long.csv +651 -0
  44. data/lib/regexp_parser/scanner/properties/short.csv +249 -0
  45. data/lib/regexp_parser/scanner/property.rl +4 -4
  46. data/lib/regexp_parser/scanner/scanner.rl +303 -368
  47. data/lib/regexp_parser/scanner.rb +1423 -1674
  48. data/lib/regexp_parser/syntax/any.rb +2 -7
  49. data/lib/regexp_parser/syntax/base.rb +92 -67
  50. data/lib/regexp_parser/syntax/token/anchor.rb +15 -0
  51. data/lib/regexp_parser/syntax/{tokens → token}/assertion.rb +2 -2
  52. data/lib/regexp_parser/syntax/token/backreference.rb +33 -0
  53. data/lib/regexp_parser/syntax/token/character_set.rb +16 -0
  54. data/lib/regexp_parser/syntax/{tokens → token}/character_type.rb +3 -3
  55. data/lib/regexp_parser/syntax/{tokens → token}/conditional.rb +3 -3
  56. data/lib/regexp_parser/syntax/token/escape.rb +33 -0
  57. data/lib/regexp_parser/syntax/{tokens → token}/group.rb +7 -7
  58. data/lib/regexp_parser/syntax/{tokens → token}/keep.rb +1 -1
  59. data/lib/regexp_parser/syntax/token/meta.rb +20 -0
  60. data/lib/regexp_parser/syntax/{tokens → token}/posix_class.rb +3 -3
  61. data/lib/regexp_parser/syntax/token/quantifier.rb +35 -0
  62. data/lib/regexp_parser/syntax/token/unicode_property.rb +751 -0
  63. data/lib/regexp_parser/syntax/token/virtual.rb +11 -0
  64. data/lib/regexp_parser/syntax/token.rb +45 -0
  65. data/lib/regexp_parser/syntax/version_lookup.rb +19 -36
  66. data/lib/regexp_parser/syntax/versions/1.8.6.rb +13 -20
  67. data/lib/regexp_parser/syntax/versions/1.9.1.rb +10 -17
  68. data/lib/regexp_parser/syntax/versions/1.9.3.rb +3 -10
  69. data/lib/regexp_parser/syntax/versions/2.0.0.rb +8 -15
  70. data/lib/regexp_parser/syntax/versions/2.2.0.rb +3 -9
  71. data/lib/regexp_parser/syntax/versions/2.3.0.rb +3 -9
  72. data/lib/regexp_parser/syntax/versions/2.4.0.rb +3 -9
  73. data/lib/regexp_parser/syntax/versions/2.4.1.rb +2 -8
  74. data/lib/regexp_parser/syntax/versions/2.5.0.rb +3 -9
  75. data/lib/regexp_parser/syntax/versions/2.6.0.rb +3 -9
  76. data/lib/regexp_parser/syntax/versions/2.6.2.rb +3 -9
  77. data/lib/regexp_parser/syntax/versions/2.6.3.rb +3 -9
  78. data/lib/regexp_parser/syntax/versions/3.1.0.rb +4 -0
  79. data/lib/regexp_parser/syntax/versions/3.2.0.rb +4 -0
  80. data/lib/regexp_parser/syntax/versions.rb +3 -1
  81. data/lib/regexp_parser/syntax.rb +8 -6
  82. data/lib/regexp_parser/token.rb +9 -20
  83. data/lib/regexp_parser/version.rb +1 -1
  84. data/lib/regexp_parser.rb +0 -2
  85. data/regexp_parser.gemspec +19 -23
  86. metadata +53 -171
  87. data/CHANGELOG.md +0 -349
  88. data/README.md +0 -470
  89. data/lib/regexp_parser/scanner/properties/long.yml +0 -594
  90. data/lib/regexp_parser/scanner/properties/short.yml +0 -237
  91. data/lib/regexp_parser/syntax/tokens/anchor.rb +0 -15
  92. data/lib/regexp_parser/syntax/tokens/backref.rb +0 -24
  93. data/lib/regexp_parser/syntax/tokens/character_set.rb +0 -13
  94. data/lib/regexp_parser/syntax/tokens/escape.rb +0 -30
  95. data/lib/regexp_parser/syntax/tokens/meta.rb +0 -13
  96. data/lib/regexp_parser/syntax/tokens/quantifier.rb +0 -35
  97. data/lib/regexp_parser/syntax/tokens/unicode_property.rb +0 -675
  98. data/lib/regexp_parser/syntax/tokens.rb +0 -45
  99. data/spec/expression/base_spec.rb +0 -94
  100. data/spec/expression/clone_spec.rb +0 -120
  101. data/spec/expression/conditional_spec.rb +0 -89
  102. data/spec/expression/free_space_spec.rb +0 -27
  103. data/spec/expression/methods/match_length_spec.rb +0 -161
  104. data/spec/expression/methods/match_spec.rb +0 -25
  105. data/spec/expression/methods/strfregexp_spec.rb +0 -224
  106. data/spec/expression/methods/tests_spec.rb +0 -99
  107. data/spec/expression/methods/traverse_spec.rb +0 -161
  108. data/spec/expression/options_spec.rb +0 -128
  109. data/spec/expression/root_spec.rb +0 -9
  110. data/spec/expression/sequence_spec.rb +0 -9
  111. data/spec/expression/subexpression_spec.rb +0 -50
  112. data/spec/expression/to_h_spec.rb +0 -26
  113. data/spec/expression/to_s_spec.rb +0 -100
  114. data/spec/lexer/all_spec.rb +0 -22
  115. data/spec/lexer/conditionals_spec.rb +0 -53
  116. data/spec/lexer/escapes_spec.rb +0 -14
  117. data/spec/lexer/keep_spec.rb +0 -10
  118. data/spec/lexer/literals_spec.rb +0 -89
  119. data/spec/lexer/nesting_spec.rb +0 -99
  120. data/spec/lexer/refcalls_spec.rb +0 -55
  121. data/spec/parser/all_spec.rb +0 -43
  122. data/spec/parser/alternation_spec.rb +0 -88
  123. data/spec/parser/anchors_spec.rb +0 -17
  124. data/spec/parser/conditionals_spec.rb +0 -179
  125. data/spec/parser/errors_spec.rb +0 -30
  126. data/spec/parser/escapes_spec.rb +0 -121
  127. data/spec/parser/free_space_spec.rb +0 -130
  128. data/spec/parser/groups_spec.rb +0 -108
  129. data/spec/parser/keep_spec.rb +0 -6
  130. data/spec/parser/posix_classes_spec.rb +0 -8
  131. data/spec/parser/properties_spec.rb +0 -115
  132. data/spec/parser/quantifiers_spec.rb +0 -51
  133. data/spec/parser/refcalls_spec.rb +0 -112
  134. data/spec/parser/set/intersections_spec.rb +0 -127
  135. data/spec/parser/set/ranges_spec.rb +0 -111
  136. data/spec/parser/sets_spec.rb +0 -178
  137. data/spec/parser/types_spec.rb +0 -18
  138. data/spec/scanner/all_spec.rb +0 -18
  139. data/spec/scanner/anchors_spec.rb +0 -21
  140. data/spec/scanner/conditionals_spec.rb +0 -128
  141. data/spec/scanner/errors_spec.rb +0 -68
  142. data/spec/scanner/escapes_spec.rb +0 -53
  143. data/spec/scanner/free_space_spec.rb +0 -133
  144. data/spec/scanner/groups_spec.rb +0 -52
  145. data/spec/scanner/keep_spec.rb +0 -10
  146. data/spec/scanner/literals_spec.rb +0 -49
  147. data/spec/scanner/meta_spec.rb +0 -18
  148. data/spec/scanner/properties_spec.rb +0 -64
  149. data/spec/scanner/quantifiers_spec.rb +0 -20
  150. data/spec/scanner/refcalls_spec.rb +0 -36
  151. data/spec/scanner/sets_spec.rb +0 -102
  152. data/spec/scanner/types_spec.rb +0 -14
  153. data/spec/spec_helper.rb +0 -15
  154. data/spec/support/runner.rb +0 -42
  155. data/spec/support/shared_examples.rb +0 -77
  156. data/spec/support/warning_extractor.rb +0 -60
  157. data/spec/syntax/syntax_spec.rb +0 -48
  158. data/spec/syntax/syntax_token_map_spec.rb +0 -23
  159. data/spec/syntax/versions/1.8.6_spec.rb +0 -17
  160. data/spec/syntax/versions/1.9.1_spec.rb +0 -10
  161. data/spec/syntax/versions/1.9.3_spec.rb +0 -9
  162. data/spec/syntax/versions/2.0.0_spec.rb +0 -13
  163. data/spec/syntax/versions/2.2.0_spec.rb +0 -9
  164. data/spec/syntax/versions/aliases_spec.rb +0 -37
  165. data/spec/token/token_spec.rb +0 -85
  166. /data/lib/regexp_parser/expression/classes/{set → character_set}/intersection.rb +0 -0
@@ -1,64 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe('Property scanning') do
4
- RSpec.shared_examples 'scan property' do |text, token|
5
- it("scans \\p{#{text}} as property #{token}") do
6
- result = RS.scan("\\p{#{text}}")[0]
7
- expect(result[0..1]).to eq [:property, token]
8
- end
9
-
10
- it("scans \\P{#{text}} as nonproperty #{token}") do
11
- result = RS.scan("\\P{#{text}}")[0]
12
- expect(result[0..1]).to eq [:nonproperty, token]
13
- end
14
-
15
- it("scans \\p{^#{text}} as nonproperty #{token}") do
16
- result = RS.scan("\\p{^#{text}}")[0]
17
- expect(result[0..1]).to eq [:nonproperty, token]
18
- end
19
-
20
- it("scans double-negated \\P{^#{text}} as property #{token}") do
21
- result = RS.scan("\\P{^#{text}}")[0]
22
- expect(result[0..1]).to eq [:property, token]
23
- end
24
- end
25
-
26
- include_examples 'scan property', 'Alnum', :alnum
27
-
28
- include_examples 'scan property', 'XPosixPunct', :xposixpunct
29
-
30
- include_examples 'scan property', 'Newline', :newline
31
-
32
- include_examples 'scan property', 'Any', :any
33
-
34
- include_examples 'scan property', 'Assigned', :assigned
35
-
36
- include_examples 'scan property', 'Age=1.1', :'age=1.1'
37
- include_examples 'scan property', 'Age=10.0', :'age=10.0'
38
-
39
- include_examples 'scan property', 'ahex', :ascii_hex_digit
40
- include_examples 'scan property', 'ASCII_Hex_Digit', :ascii_hex_digit # test underscore
41
-
42
- include_examples 'scan property', 'sd', :soft_dotted
43
- include_examples 'scan property', 'Soft-Dotted', :soft_dotted # test dash
44
-
45
- include_examples 'scan property', 'Egyp', :egyptian_hieroglyphs
46
- include_examples 'scan property', 'Egyptian Hieroglyphs', :egyptian_hieroglyphs # test whitespace
47
-
48
- include_examples 'scan property', 'Linb', :linear_b
49
- include_examples 'scan property', 'Linear-B', :linear_b # test dash
50
-
51
- include_examples 'scan property', 'InArabic', :in_arabic # test block
52
- include_examples 'scan property', 'in Arabic', :in_arabic # test block w. whitespace
53
- include_examples 'scan property', 'In_Arabic', :in_arabic # test block w. underscore
54
-
55
- include_examples 'scan property', 'Yiii', :yi
56
- include_examples 'scan property', 'Yi', :yi
57
-
58
- include_examples 'scan property', 'Zinh', :inherited
59
- include_examples 'scan property', 'Inherited', :inherited
60
- include_examples 'scan property', 'Qaai', :inherited
61
-
62
- include_examples 'scan property', 'Zzzz', :unknown
63
- include_examples 'scan property', 'Unknown', :unknown
64
- end
@@ -1,20 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe('Quantifier scanning') do
4
- include_examples 'scan', 'a?', 1 => [:quantifier, :zero_or_one, '?', 1, 2]
5
- include_examples 'scan', 'a??', 1 => [:quantifier, :zero_or_one_reluctant, '??', 1, 3]
6
- include_examples 'scan', 'a?+', 1 => [:quantifier, :zero_or_one_possessive, '?+', 1, 3]
7
-
8
- include_examples 'scan', 'a*', 1 => [:quantifier, :zero_or_more, '*', 1, 2]
9
- include_examples 'scan', 'a*?', 1 => [:quantifier, :zero_or_more_reluctant, '*?', 1, 3]
10
- include_examples 'scan', 'a*+', 1 => [:quantifier, :zero_or_more_possessive, '*+', 1, 3]
11
-
12
- include_examples 'scan', 'a+', 1 => [:quantifier, :one_or_more, '+', 1, 2]
13
- include_examples 'scan', 'a+?', 1 => [:quantifier, :one_or_more_reluctant, '+?', 1, 3]
14
- include_examples 'scan', 'a++', 1 => [:quantifier, :one_or_more_possessive, '++', 1, 3]
15
-
16
- include_examples 'scan', 'a{2}', 1 => [:quantifier, :interval, '{2}', 1, 4]
17
- include_examples 'scan', 'a{2,}', 1 => [:quantifier, :interval, '{2,}', 1, 5]
18
- include_examples 'scan', 'a{,2}', 1 => [:quantifier, :interval, '{,2}', 1, 5]
19
- include_examples 'scan', 'a{2,4}', 1 => [:quantifier, :interval, '{2,4}', 1, 6]
20
- end
@@ -1,36 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe('RefCall scanning') do
4
- # Traditional numerical group back-reference
5
- include_examples 'scan', '(abc)\1' , 3 => [:backref, :number, '\1', 5, 7]
6
-
7
- # Group back-references, named, numbered, and relative
8
- include_examples 'scan', '(?<X>abc)\k<X>', 3 => [:backref, :name_ref_ab, '\k<X>', 9, 14]
9
- include_examples 'scan', "(?<X>abc)\\k'X'", 3 => [:backref, :name_ref_sq, "\\k'X'", 9, 14]
10
-
11
- include_examples 'scan', '(abc)\k<1>', 3 => [:backref, :number_ref_ab, '\k<1>', 5, 10]
12
- include_examples 'scan', "(abc)\\k'1'", 3 => [:backref, :number_ref_sq, "\\k'1'", 5, 10]
13
-
14
- include_examples 'scan', '(abc)\k<-1>', 3 => [:backref, :number_rel_ref_ab, '\k<-1>', 5, 11]
15
- include_examples 'scan', "(abc)\\k'-1'", 3 => [:backref, :number_rel_ref_sq, "\\k'-1'", 5, 11]
16
-
17
- # Sub-expression invocation, named, numbered, and relative
18
- include_examples 'scan', '(?<X>abc)\g<X>', 3 => [:backref, :name_call_ab, '\g<X>', 9, 14]
19
- include_examples 'scan', "(?<X>abc)\\g'X'", 3 => [:backref, :name_call_sq, "\\g'X'", 9, 14]
20
-
21
- include_examples 'scan', '(abc)\g<1>', 3 => [:backref, :number_call_ab, '\g<1>', 5, 10]
22
- include_examples 'scan', "(abc)\\g'1'", 3 => [:backref, :number_call_sq, "\\g'1'", 5, 10]
23
-
24
- include_examples 'scan', '(abc)\g<-1>', 3 => [:backref, :number_rel_call_ab, '\g<-1>', 5, 11]
25
- include_examples 'scan', "(abc)\\g'-1'", 3 => [:backref, :number_rel_call_sq, "\\g'-1'", 5, 11]
26
-
27
- include_examples 'scan', '\g<+1>(abc)', 0 => [:backref, :number_rel_call_ab, '\g<+1>', 0, 6]
28
- include_examples 'scan', "\\g'+1'(abc)", 0 => [:backref, :number_rel_call_sq, "\\g'+1'", 0, 6]
29
-
30
- # Group back-references, with recursion level
31
- include_examples 'scan', '(?<X>abc)\k<X-0>', 3 => [:backref, :name_recursion_ref_ab, '\k<X-0>', 9, 16]
32
- include_examples 'scan', "(?<X>abc)\\k'X-0'", 3 => [:backref, :name_recursion_ref_sq, "\\k'X-0'", 9, 16]
33
-
34
- include_examples 'scan', '(abc)\k<1-0>', 3 => [:backref, :number_recursion_ref_ab, '\k<1-0>', 5, 12]
35
- include_examples 'scan', "(abc)\\k'1-0'", 3 => [:backref, :number_recursion_ref_sq, "\\k'1-0'", 5, 12]
36
- end
@@ -1,102 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe('Set scanning') do
4
- include_examples 'scan', /[a]/, 0 => [:set, :open, '[', 0, 1]
5
- include_examples 'scan', /[b]/, 2 => [:set, :close, ']', 2, 3]
6
- include_examples 'scan', /[^n]/, 1 => [:set, :negate, '^', 1, 2]
7
-
8
- include_examples 'scan', /[c]/, 1 => [:literal, :literal, 'c', 1, 2]
9
- include_examples 'scan', /[\b]/, 1 => [:escape, :backspace, '\b', 1, 3]
10
- include_examples 'scan', /[A\bX]/, 2 => [:escape, :backspace, '\b', 2, 4]
11
-
12
- include_examples 'scan', /[.]/, 1 => [:literal, :literal, '.', 1, 2]
13
- include_examples 'scan', /[?]/, 1 => [:literal, :literal, '?', 1, 2]
14
- include_examples 'scan', /[*]/, 1 => [:literal, :literal, '*', 1, 2]
15
- include_examples 'scan', /[+]/, 1 => [:literal, :literal, '+', 1, 2]
16
- include_examples 'scan', /[{]/, 1 => [:literal, :literal, '{', 1, 2]
17
- include_examples 'scan', /[}]/, 1 => [:literal, :literal, '}', 1, 2]
18
- include_examples 'scan', /[<]/, 1 => [:literal, :literal, '<', 1, 2]
19
- include_examples 'scan', /[>]/, 1 => [:literal, :literal, '>', 1, 2]
20
-
21
- include_examples 'scan', /[äöü]/, 2 => [:literal, :literal, 'ö', 3, 5]
22
-
23
- include_examples 'scan', /[\x20]/, 1 => [:escape, :hex, '\x20', 1, 5]
24
-
25
- include_examples 'scan', '[\.]', 1 => [:escape, :dot, '\.', 1, 3]
26
- include_examples 'scan', '[\!]', 1 => [:escape, :literal, '\!', 1, 3]
27
- include_examples 'scan', '[\#]', 1 => [:escape, :literal, '\#', 1, 3]
28
- include_examples 'scan', '[\\]]', 1 => [:escape, :set_close, '\]', 1, 3]
29
- include_examples 'scan', '[\\\\]', 1 => [:escape, :backslash, '\\\\', 1, 3]
30
- include_examples 'scan', '[\A]', 1 => [:escape, :literal, '\A', 1, 3]
31
- include_examples 'scan', '[\z]', 1 => [:escape, :literal, '\z', 1, 3]
32
- include_examples 'scan', '[\g]', 1 => [:escape, :literal, '\g', 1, 3]
33
- include_examples 'scan', '[\K]', 1 => [:escape, :literal, '\K', 1, 3]
34
- include_examples 'scan', '[\R]', 1 => [:escape, :literal, '\R', 1, 3]
35
- include_examples 'scan', '[\X]', 1 => [:escape, :literal, '\X', 1, 3]
36
- include_examples 'scan', '[\c2]', 1 => [:escape, :literal, '\c', 1, 3]
37
- include_examples 'scan', '[\B]', 1 => [:escape, :literal, '\B', 1, 3]
38
- include_examples 'scan', '[a\-c]', 2 => [:escape, :literal, '\-', 2, 4]
39
-
40
- include_examples 'scan', /[\d]/, 1 => [:type, :digit, '\d', 1, 3]
41
- include_examples 'scan', /[\da-z]/, 1 => [:type, :digit, '\d', 1, 3]
42
- include_examples 'scan', /[\D]/, 1 => [:type, :nondigit, '\D', 1, 3]
43
-
44
- include_examples 'scan', /[\h]/, 1 => [:type, :hex, '\h', 1, 3]
45
- include_examples 'scan', /[\H]/, 1 => [:type, :nonhex, '\H', 1, 3]
46
-
47
- include_examples 'scan', /[\s]/, 1 => [:type, :space, '\s', 1, 3]
48
- include_examples 'scan', /[\S]/, 1 => [:type, :nonspace, '\S', 1, 3]
49
-
50
- include_examples 'scan', /[\w]/, 1 => [:type, :word, '\w', 1, 3]
51
- include_examples 'scan', /[\W]/, 1 => [:type, :nonword, '\W', 1, 3]
52
-
53
- include_examples 'scan', /[a-b]/, 1 => [:literal, :literal, 'a', 1, 2]
54
- include_examples 'scan', /[a-c]/, 2 => [:set, :range, '-', 2, 3]
55
- include_examples 'scan', /[a-d]/, 3 => [:literal, :literal, 'd', 3, 4]
56
- include_examples 'scan', /[a-b-]/, 4 => [:literal, :literal, '-', 4, 5]
57
- include_examples 'scan', /[-a]/, 1 => [:literal, :literal, '-', 1, 2]
58
- include_examples 'scan', /[a-c^]/, 4 => [:literal, :literal, '^', 4, 5]
59
- include_examples 'scan', /[a-bd-f]/, 2 => [:set, :range, '-', 2, 3]
60
- include_examples 'scan', /[a-cd-f]/, 5 => [:set, :range, '-', 5, 6]
61
-
62
- include_examples 'scan', /[a[:digit:]c]/, 2 => [:posixclass, :digit, '[:digit:]', 2, 11]
63
- include_examples 'scan', /[[:digit:][:space:]]/, 2 => [:posixclass, :space, '[:space:]', 10, 19]
64
- include_examples 'scan', /[[:^digit:]]/, 1 => [:nonposixclass, :digit, '[:^digit:]', 1, 11]
65
-
66
- include_examples 'scan', /[a[.a-b.]c]/, 2 => [:set, :collation, '[.a-b.]', 2, 9]
67
- include_examples 'scan', /[a[=e=]c]/, 2 => [:set, :equivalent, '[=e=]', 2, 7]
68
-
69
- include_examples 'scan', /[a-d&&g-h]/, 4 => [:set, :intersection, '&&', 4, 6]
70
- include_examples 'scan', /[a&&]/, 2 => [:set, :intersection, '&&', 2, 4]
71
- include_examples 'scan', /[&&z]/, 1 => [:set, :intersection, '&&', 1, 3]
72
-
73
- include_examples 'scan', /[a\p{digit}c]/, 2 => [:property, :digit, '\p{digit}', 2, 11]
74
- include_examples 'scan', /[a\P{digit}c]/, 2 => [:nonproperty, :digit, '\P{digit}', 2, 11]
75
- include_examples 'scan', /[a\p{^digit}c]/, 2 => [:nonproperty, :digit, '\p{^digit}', 2, 12]
76
- include_examples 'scan', /[a\P{^digit}c]/, 2 => [:property, :digit, '\P{^digit}', 2, 12]
77
-
78
- include_examples 'scan', /[a\p{ALPHA}c]/, 2 => [:property, :alpha, '\p{ALPHA}', 2, 11]
79
- include_examples 'scan', /[a\p{P}c]/, 2 => [:property, :punctuation,'\p{P}', 2, 7]
80
- include_examples 'scan', /[a\p{P}\P{P}c]/, 3 => [:nonproperty, :punctuation,'\P{P}', 7, 12]
81
-
82
- include_examples 'scan', /[\x20-\x27]/,
83
- 1 => [:escape, :hex, '\x20', 1, 5],
84
- 2 => [:set, :range, '-', 5, 6],
85
- 3 => [:escape, :hex, '\x27', 6, 10]
86
-
87
- include_examples 'scan', /[a-w&&[^c-g]z]/,
88
- 5 => [:set, :open, '[', 6, 7],
89
- 6 => [:set, :negate, '^', 7, 8],
90
- 8 => [:set, :range, '-', 9, 10],
91
- 10=> [:set, :close, ']', 11, 12]
92
-
93
- specify('set literal encoding') do
94
- text = RS.scan('[a]')[1][2].to_s
95
- expect(text).to eq 'a'
96
- expect(text.encoding.to_s).to eq 'UTF-8'
97
-
98
- text = RS.scan("[\u{1F632}]")[1][2].to_s
99
- expect(text).to eq "\u{1F632}"
100
- expect(text.encoding.to_s).to eq 'UTF-8'
101
- end
102
- end
@@ -1,14 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe('Type scanning') do
4
- include_examples 'scan', 'a\\dc', 1 => [:type, :digit, '\\d', 1, 3]
5
- include_examples 'scan', 'a\\Dc', 1 => [:type, :nondigit, '\\D', 1, 3]
6
- include_examples 'scan', 'a\\hc', 1 => [:type, :hex, '\\h', 1, 3]
7
- include_examples 'scan', 'a\\Hc', 1 => [:type, :nonhex, '\\H', 1, 3]
8
- include_examples 'scan', 'a\\sc', 1 => [:type, :space, '\\s', 1, 3]
9
- include_examples 'scan', 'a\\Sc', 1 => [:type, :nonspace, '\\S', 1, 3]
10
- include_examples 'scan', 'a\\wc', 1 => [:type, :word, '\\w', 1, 3]
11
- include_examples 'scan', 'a\\Wc', 1 => [:type, :nonword, '\\W', 1, 3]
12
- include_examples 'scan', 'a\\Rc', 1 => [:type, :linebreak, '\\R', 1, 3]
13
- include_examples 'scan', 'a\\Xc', 1 => [:type, :xgrapheme, '\\X', 1, 3]
14
- end
data/spec/spec_helper.rb DELETED
@@ -1,15 +0,0 @@
1
- require 'regexp_parser'
2
- require 'regexp_property_values'
3
- require_relative 'support/shared_examples'
4
-
5
- RS = Regexp::Scanner
6
- RL = Regexp::Lexer
7
- RP = Regexp::Parser
8
- RE = Regexp::Expression
9
- T = Regexp::Syntax::Token
10
-
11
- include Regexp::Expression
12
-
13
- def ruby_version_at_least(version)
14
- Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new(version)
15
- end
@@ -1,42 +0,0 @@
1
- require 'pathname'
2
- require 'rspec'
3
-
4
- module RegexpParserSpec
5
- class Runner
6
- def initialize(arguments, warning_whitelist)
7
- @arguments = arguments
8
- @warning_whitelist = warning_whitelist
9
- end
10
-
11
- def run
12
- spec_status = nil
13
-
14
- Warning::Filter.new(warning_whitelist).assert_expected_warnings_only do
15
- setup
16
- spec_status = run_rspec
17
- end
18
-
19
- spec_status
20
- end
21
-
22
- private
23
-
24
- def setup
25
- $VERBOSE = true
26
-
27
- spec_files.each(&method(:require))
28
- end
29
-
30
- def run_rspec
31
- RSpec::Core::Runner.run([])
32
- end
33
-
34
- def spec_files
35
- arguments
36
- .map { |path| Pathname.new(path).expand_path.freeze }
37
- .select(&:file?)
38
- end
39
-
40
- attr_reader :arguments, :warning_whitelist
41
- end
42
- end
@@ -1,77 +0,0 @@
1
- RSpec.shared_examples 'syntax' do |klass, opts|
2
- opts[:implements].each do |type, tokens|
3
- tokens.each do |token|
4
- it("implements #{token} #{type}") do
5
- expect(klass.implements?(type, token)).to be true
6
- end
7
- end
8
- end
9
-
10
- opts[:excludes] && opts[:excludes].each do |type, tokens|
11
- tokens.each do |token|
12
- it("does not implement #{token} #{type}") do
13
- expect(klass.implements?(type, token)).to be false
14
- end
15
- end
16
- end
17
- end
18
-
19
- RSpec.shared_examples 'scan' do |pattern, checks|
20
- context "given the pattern #{pattern}" do
21
- before(:all) { @tokens = Regexp::Scanner.scan(pattern) }
22
-
23
- checks.each do |index, (type, token, text, ts, te)|
24
- it "scans token #{index} as #{token} #{type} at #{ts}..#{te}" do
25
- result = @tokens.at(index)
26
-
27
- expect(result[0]).to eq type
28
- expect(result[1]).to eq token
29
- expect(result[2]).to eq text
30
- expect(result[3]).to eq ts
31
- expect(result[4]).to eq te
32
- end
33
- end
34
- end
35
- end
36
-
37
- RSpec.shared_examples 'lex' do |pattern, checks|
38
- context "given the pattern #{pattern}" do
39
- before(:all) { @tokens = Regexp::Lexer.lex(pattern) }
40
-
41
- checks.each do |index, (type, token, text, ts, te, lvl, set_lvl, cond_lvl)|
42
- it "lexes token #{index} as #{token} #{type} at #{lvl}, #{set_lvl}, #{cond_lvl}" do
43
- struct = @tokens.at(index)
44
-
45
- expect(struct.type).to eq type
46
- expect(struct.token).to eq token
47
- expect(struct.text).to eq text
48
- expect(struct.ts).to eq ts
49
- expect(struct.te).to eq te
50
- expect(struct.level).to eq lvl
51
- expect(struct.set_level).to eq set_lvl
52
- expect(struct.conditional_level).to eq cond_lvl
53
- end
54
- end
55
- end
56
- end
57
-
58
- RSpec.shared_examples 'parse' do |pattern, checks|
59
- context "given the pattern #{pattern}" do
60
- before(:all) { @root = Regexp::Parser.parse(pattern, '*') }
61
-
62
- checks.each do |path, (type, token, klass, attributes)|
63
- it "parses expression at #{path} as #{klass}" do
64
- exp = @root.dig(*path)
65
-
66
- expect(exp).to be_instance_of(klass)
67
- expect(exp.type).to eq type
68
- expect(exp.token).to eq token
69
-
70
- attributes && attributes.each do |method, value|
71
- expect(exp.send(method)).to eq(value),
72
- "expected expression at #{path} to have #{method} #{value}"
73
- end
74
- end
75
- end
76
- end
77
- end
@@ -1,60 +0,0 @@
1
- require 'set'
2
- require 'delegate'
3
-
4
- module RegexpParserSpec
5
- class Warning
6
- class UnexpectedWarnings < StandardError
7
- MSG = 'Unexpected warnings: %s'.freeze
8
-
9
- def initialize(warnings)
10
- super(MSG % warnings.join("\n"))
11
- end
12
- end
13
-
14
- class Filter
15
- def initialize(whitelist)
16
- @whitelist = whitelist
17
- end
18
-
19
- def assert_expected_warnings_only
20
- original = $stderr
21
- $stderr = Extractor.new(original, @whitelist)
22
-
23
- yield
24
-
25
- assert_no_warnings($stderr.warnings)
26
- ensure
27
- $stderr = original
28
- end
29
-
30
- private
31
-
32
- def assert_no_warnings(warnings)
33
- raise UnexpectedWarnings, warnings.to_a if warnings.any?
34
- end
35
- end
36
-
37
- class Extractor < DelegateClass(IO)
38
- PATTERN = /\A(?:.+):(?:\d+): warning: (?:.+)\n\z/
39
-
40
- def initialize(io, whitelist)
41
- @whitelist = whitelist
42
- @warnings = Set.new
43
- super(io)
44
- end
45
-
46
- def write(message)
47
- return super if PATTERN !~ message
48
-
49
- warning = message.chomp
50
- @warnings << warning if @whitelist.none?(&warning.method(:include?))
51
-
52
- self
53
- end
54
-
55
- def warnings
56
- @warnings.dup.freeze
57
- end
58
- end
59
- end
60
- end
@@ -1,48 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe(Regexp::Syntax) do
4
- specify('unknown name') do
5
- expect { Regexp::Syntax.new('ruby/1.0') }.to raise_error(Regexp::Syntax::UnknownSyntaxNameError)
6
- end
7
-
8
- specify('new') do
9
- expect(Regexp::Syntax.new('ruby/1.9.3')).to be_instance_of(Regexp::Syntax::V1_9_3)
10
- end
11
-
12
- specify('new any') do
13
- expect(Regexp::Syntax.new('any')).to be_instance_of(Regexp::Syntax::Any)
14
- expect(Regexp::Syntax.new('*')).to be_instance_of(Regexp::Syntax::Any)
15
- end
16
-
17
- specify('not implemented') do
18
- expect { RP.parse('\\p{alpha}', 'ruby/1.8') }.to raise_error(Regexp::Syntax::NotImplementedError)
19
- end
20
-
21
- specify('supported?') do
22
- expect(Regexp::Syntax.supported?('ruby/1.1.1')).to be false
23
- expect(Regexp::Syntax.supported?('ruby/2.4.3')).to be true
24
- expect(Regexp::Syntax.supported?('ruby/2.5')).to be true
25
- end
26
-
27
- specify('invalid version') do
28
- expect { Regexp::Syntax.version_class('2.0.0') }.to raise_error(Regexp::Syntax::InvalidVersionNameError)
29
-
30
- expect { Regexp::Syntax.version_class('ruby/20') }.to raise_error(Regexp::Syntax::InvalidVersionNameError)
31
- end
32
-
33
- specify('version class tiny version') do
34
- expect(Regexp::Syntax.version_class('ruby/1.9.3')).to eq Regexp::Syntax::V1_9_3
35
-
36
- expect(Regexp::Syntax.version_class('ruby/2.3.1')).to eq Regexp::Syntax::V2_3_1
37
- end
38
-
39
- specify('version class minor version') do
40
- expect(Regexp::Syntax.version_class('ruby/1.9')).to eq Regexp::Syntax::V1_9
41
-
42
- expect(Regexp::Syntax.version_class('ruby/2.3')).to eq Regexp::Syntax::V2_3
43
- end
44
-
45
- specify('raises for unknown constant lookups') do
46
- expect { Regexp::Syntax::V1 }.to raise_error(/V1/)
47
- end
48
- end
@@ -1,23 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe(Regexp::Syntax::Token::Map) do
4
- let(:map) { Regexp::Syntax::Token::Map }
5
-
6
- specify('is complete') do
7
- latest_syntax = Regexp::Syntax.new('ruby/2.9')
8
-
9
- latest_syntax.features.each do |type, tokens|
10
- tokens.each { |token| expect(map[type]).to include(token) }
11
- end
12
- end
13
-
14
- specify('contains no duplicate type/token combinations') do
15
- combinations = map.flat_map do |type, tokens|
16
- tokens.map { |token| "#{type} #{token}" }
17
- end
18
-
19
- non_uniq = combinations.group_by { |str| str }.select { |_, v| v.count > 1 }
20
-
21
- expect(non_uniq.keys).to be_empty
22
- end
23
- end
@@ -1,17 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe(Regexp::Syntax::V1_8_6) do
4
- include_examples 'syntax', Regexp::Syntax.new('ruby/1.8.6'),
5
- implements: {
6
- assertion: T::Assertion::Lookahead,
7
- backref: [:number],
8
- escape: T::Escape::Basic + T::Escape::ASCII + T::Escape::Meta + T::Escape::Control,
9
- group: T::Group::V1_8_6,
10
- quantifier: T::Quantifier::Greedy + T::Quantifier::Reluctant + T::Quantifier::Interval + T::Quantifier::IntervalReluctant
11
- },
12
- excludes: {
13
- assertion: T::Assertion::Lookbehind,
14
- backref: T::Backreference::All - [:number] + T::SubexpressionCall::All,
15
- quantifier: T::Quantifier::Possessive
16
- }
17
- end
@@ -1,10 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe(Regexp::Syntax::V1_9_1) do
4
- include_examples 'syntax', Regexp::Syntax.new('ruby/1.9.1'),
5
- implements: {
6
- escape: T::Escape::Hex + T::Escape::Octal + T::Escape::Unicode,
7
- type: T::CharacterType::Hex,
8
- quantifier: T::Quantifier::Greedy + T::Quantifier::Reluctant + T::Quantifier::Possessive
9
- }
10
- end
@@ -1,9 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe(Regexp::Syntax::V1_9_3) do
4
- include_examples 'syntax', Regexp::Syntax.new('ruby/1.9.3'),
5
- implements: {
6
- property: T::UnicodeProperty::Script_V1_9_3 + T::UnicodeProperty::Age_V1_9_3,
7
- nonproperty: T::UnicodeProperty::Script_V1_9_3 + T::UnicodeProperty::Age_V1_9_3
8
- }
9
- end
@@ -1,13 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe(Regexp::Syntax::V2_0_0) do
4
- include_examples 'syntax', Regexp::Syntax.new('ruby/2.0.0'),
5
- implements: {
6
- property: T::UnicodeProperty::Age_V2_0_0,
7
- nonproperty: T::UnicodeProperty::Age_V2_0_0
8
- },
9
- excludes: {
10
- property: [:newline],
11
- nonproperty: [:newline]
12
- }
13
- end
@@ -1,9 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe(Regexp::Syntax::V2_2_0) do
4
- include_examples 'syntax', Regexp::Syntax.new('ruby/2.2.0'),
5
- implements: {
6
- property: T::UnicodeProperty::Script_V2_2_0 + T::UnicodeProperty::Age_V2_2_0,
7
- nonproperty: T::UnicodeProperty::Script_V2_2_0 + T::UnicodeProperty::Age_V2_2_0
8
- }
9
- end
@@ -1,37 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe(Regexp::Syntax) do
4
- RSpec.shared_examples 'syntax alias' do |string, klass|
5
- it "aliases #{string} to #{klass}" do
6
- syntax = Regexp::Syntax.new(string)
7
- expect(syntax).to be_a klass
8
- end
9
- end
10
-
11
- include_examples 'syntax alias', 'ruby/1.8.6', Regexp::Syntax::V1_8_6
12
- include_examples 'syntax alias', 'ruby/1.8', Regexp::Syntax::V1_8_6
13
- include_examples 'syntax alias', 'ruby/1.9.1', Regexp::Syntax::V1_9_1
14
- include_examples 'syntax alias', 'ruby/1.9', Regexp::Syntax::V1_9_3
15
- include_examples 'syntax alias', 'ruby/2.0.0', Regexp::Syntax::V1_9
16
- include_examples 'syntax alias', 'ruby/2.0', Regexp::Syntax::V2_0_0
17
- include_examples 'syntax alias', 'ruby/2.1', Regexp::Syntax::V2_0_0
18
- include_examples 'syntax alias', 'ruby/2.2.0', Regexp::Syntax::V2_0_0
19
- include_examples 'syntax alias', 'ruby/2.2.10', Regexp::Syntax::V2_0_0
20
- include_examples 'syntax alias', 'ruby/2.2', Regexp::Syntax::V2_0_0
21
- include_examples 'syntax alias', 'ruby/2.3.0', Regexp::Syntax::V2_3_0
22
- include_examples 'syntax alias', 'ruby/2.3', Regexp::Syntax::V2_3_0
23
- include_examples 'syntax alias', 'ruby/2.4.0', Regexp::Syntax::V2_4_0
24
- include_examples 'syntax alias', 'ruby/2.4.1', Regexp::Syntax::V2_4_1
25
- include_examples 'syntax alias', 'ruby/2.5.0', Regexp::Syntax::V2_4_1
26
- include_examples 'syntax alias', 'ruby/2.5', Regexp::Syntax::V2_5_0
27
- include_examples 'syntax alias', 'ruby/2.6.0', Regexp::Syntax::V2_5_0
28
- include_examples 'syntax alias', 'ruby/2.6.2', Regexp::Syntax::V2_6_2
29
- include_examples 'syntax alias', 'ruby/2.6.3', Regexp::Syntax::V2_6_3
30
- include_examples 'syntax alias', 'ruby/2.6', Regexp::Syntax::V2_6_3
31
-
32
- specify('future alias warning') do
33
- expect { Regexp::Syntax.new('ruby/5.0') }
34
- .to output(/This library .* but you are running .* \(feature set of .*\)/)
35
- .to_stderr
36
- end
37
- end