regexp_parser 1.7.0 → 2.8.3

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 (165) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +8 -2
  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} +3 -4
  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 -1
  20. data/lib/regexp_parser/expression/classes/root.rb +4 -19
  21. data/lib/regexp_parser/expression/classes/{property.rb → unicode_property.rb} +5 -3
  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/parts.rb +23 -0
  26. data/lib/regexp_parser/expression/methods/printing.rb +26 -0
  27. data/lib/regexp_parser/expression/methods/strfregexp.rb +1 -1
  28. data/lib/regexp_parser/expression/methods/tests.rb +47 -1
  29. data/lib/regexp_parser/expression/methods/traverse.rb +34 -18
  30. data/lib/regexp_parser/expression/quantifier.rb +57 -17
  31. data/lib/regexp_parser/expression/sequence.rb +11 -47
  32. data/lib/regexp_parser/expression/sequence_operation.rb +4 -9
  33. data/lib/regexp_parser/expression/shared.rb +111 -0
  34. data/lib/regexp_parser/expression/subexpression.rb +27 -19
  35. data/lib/regexp_parser/expression.rb +14 -141
  36. data/lib/regexp_parser/lexer.rb +83 -41
  37. data/lib/regexp_parser/parser.rb +371 -429
  38. data/lib/regexp_parser/scanner/char_type.rl +11 -11
  39. data/lib/regexp_parser/scanner/errors/premature_end_error.rb +8 -0
  40. data/lib/regexp_parser/scanner/errors/scanner_error.rb +6 -0
  41. data/lib/regexp_parser/scanner/errors/validation_error.rb +63 -0
  42. data/lib/regexp_parser/scanner/properties/long.csv +633 -0
  43. data/lib/regexp_parser/scanner/properties/short.csv +248 -0
  44. data/lib/regexp_parser/scanner/property.rl +4 -4
  45. data/lib/regexp_parser/scanner/scanner.rl +303 -368
  46. data/lib/regexp_parser/scanner.rb +1423 -1674
  47. data/lib/regexp_parser/syntax/any.rb +2 -7
  48. data/lib/regexp_parser/syntax/base.rb +92 -67
  49. data/lib/regexp_parser/syntax/token/anchor.rb +15 -0
  50. data/lib/regexp_parser/syntax/{tokens → token}/assertion.rb +2 -2
  51. data/lib/regexp_parser/syntax/token/backreference.rb +33 -0
  52. data/lib/regexp_parser/syntax/token/character_set.rb +16 -0
  53. data/lib/regexp_parser/syntax/{tokens → token}/character_type.rb +3 -3
  54. data/lib/regexp_parser/syntax/{tokens → token}/conditional.rb +3 -3
  55. data/lib/regexp_parser/syntax/token/escape.rb +33 -0
  56. data/lib/regexp_parser/syntax/{tokens → token}/group.rb +7 -7
  57. data/lib/regexp_parser/syntax/{tokens → token}/keep.rb +1 -1
  58. data/lib/regexp_parser/syntax/token/meta.rb +20 -0
  59. data/lib/regexp_parser/syntax/{tokens → token}/posix_class.rb +3 -3
  60. data/lib/regexp_parser/syntax/token/quantifier.rb +35 -0
  61. data/lib/regexp_parser/syntax/token/unicode_property.rb +733 -0
  62. data/lib/regexp_parser/syntax/token/virtual.rb +11 -0
  63. data/lib/regexp_parser/syntax/token.rb +45 -0
  64. data/lib/regexp_parser/syntax/version_lookup.rb +19 -36
  65. data/lib/regexp_parser/syntax/versions/1.8.6.rb +13 -20
  66. data/lib/regexp_parser/syntax/versions/1.9.1.rb +10 -17
  67. data/lib/regexp_parser/syntax/versions/1.9.3.rb +3 -10
  68. data/lib/regexp_parser/syntax/versions/2.0.0.rb +8 -15
  69. data/lib/regexp_parser/syntax/versions/2.2.0.rb +3 -9
  70. data/lib/regexp_parser/syntax/versions/2.3.0.rb +3 -9
  71. data/lib/regexp_parser/syntax/versions/2.4.0.rb +3 -9
  72. data/lib/regexp_parser/syntax/versions/2.4.1.rb +2 -8
  73. data/lib/regexp_parser/syntax/versions/2.5.0.rb +3 -9
  74. data/lib/regexp_parser/syntax/versions/2.6.0.rb +3 -9
  75. data/lib/regexp_parser/syntax/versions/2.6.2.rb +3 -9
  76. data/lib/regexp_parser/syntax/versions/2.6.3.rb +3 -9
  77. data/lib/regexp_parser/syntax/versions/3.1.0.rb +4 -0
  78. data/lib/regexp_parser/syntax/versions/3.2.0.rb +4 -0
  79. data/lib/regexp_parser/syntax/versions.rb +3 -1
  80. data/lib/regexp_parser/syntax.rb +8 -6
  81. data/lib/regexp_parser/token.rb +9 -20
  82. data/lib/regexp_parser/version.rb +1 -1
  83. data/lib/regexp_parser.rb +0 -2
  84. data/regexp_parser.gemspec +19 -23
  85. metadata +52 -171
  86. data/CHANGELOG.md +0 -349
  87. data/README.md +0 -470
  88. data/lib/regexp_parser/scanner/properties/long.yml +0 -594
  89. data/lib/regexp_parser/scanner/properties/short.yml +0 -237
  90. data/lib/regexp_parser/syntax/tokens/anchor.rb +0 -15
  91. data/lib/regexp_parser/syntax/tokens/backref.rb +0 -24
  92. data/lib/regexp_parser/syntax/tokens/character_set.rb +0 -13
  93. data/lib/regexp_parser/syntax/tokens/escape.rb +0 -30
  94. data/lib/regexp_parser/syntax/tokens/meta.rb +0 -13
  95. data/lib/regexp_parser/syntax/tokens/quantifier.rb +0 -35
  96. data/lib/regexp_parser/syntax/tokens/unicode_property.rb +0 -675
  97. data/lib/regexp_parser/syntax/tokens.rb +0 -45
  98. data/spec/expression/base_spec.rb +0 -94
  99. data/spec/expression/clone_spec.rb +0 -120
  100. data/spec/expression/conditional_spec.rb +0 -89
  101. data/spec/expression/free_space_spec.rb +0 -27
  102. data/spec/expression/methods/match_length_spec.rb +0 -161
  103. data/spec/expression/methods/match_spec.rb +0 -25
  104. data/spec/expression/methods/strfregexp_spec.rb +0 -224
  105. data/spec/expression/methods/tests_spec.rb +0 -99
  106. data/spec/expression/methods/traverse_spec.rb +0 -161
  107. data/spec/expression/options_spec.rb +0 -128
  108. data/spec/expression/root_spec.rb +0 -9
  109. data/spec/expression/sequence_spec.rb +0 -9
  110. data/spec/expression/subexpression_spec.rb +0 -50
  111. data/spec/expression/to_h_spec.rb +0 -26
  112. data/spec/expression/to_s_spec.rb +0 -100
  113. data/spec/lexer/all_spec.rb +0 -22
  114. data/spec/lexer/conditionals_spec.rb +0 -53
  115. data/spec/lexer/escapes_spec.rb +0 -14
  116. data/spec/lexer/keep_spec.rb +0 -10
  117. data/spec/lexer/literals_spec.rb +0 -89
  118. data/spec/lexer/nesting_spec.rb +0 -99
  119. data/spec/lexer/refcalls_spec.rb +0 -55
  120. data/spec/parser/all_spec.rb +0 -43
  121. data/spec/parser/alternation_spec.rb +0 -88
  122. data/spec/parser/anchors_spec.rb +0 -17
  123. data/spec/parser/conditionals_spec.rb +0 -179
  124. data/spec/parser/errors_spec.rb +0 -30
  125. data/spec/parser/escapes_spec.rb +0 -121
  126. data/spec/parser/free_space_spec.rb +0 -130
  127. data/spec/parser/groups_spec.rb +0 -108
  128. data/spec/parser/keep_spec.rb +0 -6
  129. data/spec/parser/posix_classes_spec.rb +0 -8
  130. data/spec/parser/properties_spec.rb +0 -115
  131. data/spec/parser/quantifiers_spec.rb +0 -51
  132. data/spec/parser/refcalls_spec.rb +0 -112
  133. data/spec/parser/set/intersections_spec.rb +0 -127
  134. data/spec/parser/set/ranges_spec.rb +0 -111
  135. data/spec/parser/sets_spec.rb +0 -178
  136. data/spec/parser/types_spec.rb +0 -18
  137. data/spec/scanner/all_spec.rb +0 -18
  138. data/spec/scanner/anchors_spec.rb +0 -21
  139. data/spec/scanner/conditionals_spec.rb +0 -128
  140. data/spec/scanner/errors_spec.rb +0 -68
  141. data/spec/scanner/escapes_spec.rb +0 -53
  142. data/spec/scanner/free_space_spec.rb +0 -133
  143. data/spec/scanner/groups_spec.rb +0 -52
  144. data/spec/scanner/keep_spec.rb +0 -10
  145. data/spec/scanner/literals_spec.rb +0 -49
  146. data/spec/scanner/meta_spec.rb +0 -18
  147. data/spec/scanner/properties_spec.rb +0 -64
  148. data/spec/scanner/quantifiers_spec.rb +0 -20
  149. data/spec/scanner/refcalls_spec.rb +0 -36
  150. data/spec/scanner/sets_spec.rb +0 -102
  151. data/spec/scanner/types_spec.rb +0 -14
  152. data/spec/spec_helper.rb +0 -15
  153. data/spec/support/runner.rb +0 -42
  154. data/spec/support/shared_examples.rb +0 -77
  155. data/spec/support/warning_extractor.rb +0 -60
  156. data/spec/syntax/syntax_spec.rb +0 -48
  157. data/spec/syntax/syntax_token_map_spec.rb +0 -23
  158. data/spec/syntax/versions/1.8.6_spec.rb +0 -17
  159. data/spec/syntax/versions/1.9.1_spec.rb +0 -10
  160. data/spec/syntax/versions/1.9.3_spec.rb +0 -9
  161. data/spec/syntax/versions/2.0.0_spec.rb +0 -13
  162. data/spec/syntax/versions/2.2.0_spec.rb +0 -9
  163. data/spec/syntax/versions/aliases_spec.rb +0 -37
  164. data/spec/token/token_spec.rb +0 -85
  165. /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