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,115 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe('Property parsing') do
4
- example_props = [
5
- 'Alnum',
6
- 'Any',
7
- 'Age=1.1',
8
- 'Dash',
9
- 'di',
10
- 'Default_Ignorable_Code_Point',
11
- 'Math',
12
- 'Noncharacter-Code_Point', # test dash
13
- 'sd',
14
- 'Soft Dotted', # test whitespace
15
- 'sterm',
16
- 'xidc',
17
- 'XID_Continue',
18
- 'Emoji',
19
- 'InChessSymbols'
20
- ]
21
-
22
- example_props.each do |name|
23
- it("parses property #{name}") do
24
- exp = RP.parse("ab\\p{#{name}}", '*').last
25
-
26
- expect(exp).to be_a(UnicodeProperty::Base)
27
- expect(exp.type).to eq :property
28
- expect(exp.name).to eq name
29
- end
30
-
31
- it("parses nonproperty #{name}") do
32
- exp = RP.parse("ab\\P{#{name}}", '*').last
33
-
34
- expect(exp).to be_a(UnicodeProperty::Base)
35
- expect(exp.type).to eq :nonproperty
36
- expect(exp.name).to eq name
37
- end
38
- end
39
-
40
- specify('parse all properties of current ruby') do
41
- unsupported = RegexpPropertyValues.all_for_current_ruby.reject do |prop|
42
- RP.parse("\\p{#{prop}}") rescue false
43
- end
44
- expect(unsupported).to be_empty
45
- end
46
-
47
- specify('parse property negative') do
48
- root = RP.parse('ab\p{L}cd', 'ruby/1.9')
49
- expect(root[1]).not_to be_negative
50
- end
51
-
52
- specify('parse nonproperty negative') do
53
- root = RP.parse('ab\P{L}cd', 'ruby/1.9')
54
- expect(root[1]).to be_negative
55
- end
56
-
57
- specify('parse caret nonproperty negative') do
58
- root = RP.parse('ab\p{^L}cd', 'ruby/1.9')
59
- expect(root[1]).to be_negative
60
- end
61
-
62
- specify('parse double negated property negative') do
63
- root = RP.parse('ab\P{^L}cd', 'ruby/1.9')
64
- expect(root[1]).not_to be_negative
65
- end
66
-
67
- specify('parse property shortcut') do
68
- expect(RP.parse('\p{lowercase_letter}')[0].shortcut).to eq 'll'
69
- expect(RP.parse('\p{sc}')[0].shortcut).to eq 'sc'
70
- expect(RP.parse('\p{in_bengali}')[0].shortcut).to be_nil
71
- end
72
-
73
- specify('parse property age') do
74
- root = RP.parse('ab\p{age=5.2}cd', 'ruby/1.9')
75
- expect(root[1]).to be_a(UnicodeProperty::Age)
76
- end
77
-
78
- specify('parse property derived') do
79
- root = RP.parse('ab\p{Math}cd', 'ruby/1.9')
80
- expect(root[1]).to be_a(UnicodeProperty::Derived)
81
- end
82
-
83
- specify('parse property script') do
84
- root = RP.parse('ab\p{Hiragana}cd', 'ruby/1.9')
85
- expect(root[1]).to be_a(UnicodeProperty::Script)
86
- end
87
-
88
- specify('parse property script V1 9 3') do
89
- root = RP.parse('ab\p{Brahmi}cd', 'ruby/1.9.3')
90
- expect(root[1]).to be_a(UnicodeProperty::Script)
91
- end
92
-
93
- specify('parse property script V2 2 0') do
94
- root = RP.parse('ab\p{Caucasian_Albanian}cd', 'ruby/2.2')
95
- expect(root[1]).to be_a(UnicodeProperty::Script)
96
- end
97
-
98
- specify('parse property block') do
99
- root = RP.parse('ab\p{InArmenian}cd', 'ruby/1.9')
100
- expect(root[1]).to be_a(UnicodeProperty::Block)
101
- end
102
-
103
- specify('parse property following literal') do
104
- root = RP.parse('ab\p{Lu}cd', 'ruby/1.9')
105
- expect(root[2]).to be_a(Literal)
106
- end
107
-
108
- specify('parse abandoned newline property') do
109
- root = RP.parse('\p{newline}', 'ruby/1.9')
110
- expect(root.expressions.last).to be_a(UnicodeProperty::Base)
111
-
112
- expect { RP.parse('\p{newline}', 'ruby/2.0') }
113
- .to raise_error(Regexp::Syntax::NotImplementedError)
114
- end
115
- end
@@ -1,51 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe('Quantifier parsing') do
4
- RSpec.shared_examples 'quantifier' do |pattern, text, mode, token, min, max|
5
- it "parses the quantifier in #{pattern} as #{mode} #{token}" do
6
- root = RP.parse(pattern, '*')
7
- exp = root[0]
8
-
9
- expect(exp).to be_quantified
10
- expect(exp.quantifier.token).to eq token
11
- expect(exp.quantifier.min).to eq min
12
- expect(exp.quantifier.max).to eq max
13
- expect(exp.quantifier.mode).to eq mode
14
- end
15
- end
16
-
17
- include_examples 'quantifier', /a?b/, '?', :greedy, :zero_or_one, 0, 1
18
- include_examples 'quantifier', /a??b/, '??', :reluctant, :zero_or_one, 0, 1
19
- include_examples 'quantifier', /a?+b/, '?+', :possessive, :zero_or_one, 0, 1
20
- include_examples 'quantifier', /a*b/, '*', :greedy, :zero_or_more, 0, -1
21
- include_examples 'quantifier', /a*?b/, '*?', :reluctant, :zero_or_more, 0, -1
22
- include_examples 'quantifier', /a*+b/, '*+', :possessive, :zero_or_more, 0, -1
23
- include_examples 'quantifier', /a+b/, '+', :greedy, :one_or_more, 1, -1
24
- include_examples 'quantifier', /a+?b/, '+?', :reluctant, :one_or_more, 1, -1
25
- include_examples 'quantifier', /a++b/, '++', :possessive, :one_or_more, 1, -1
26
- include_examples 'quantifier', /a{2,4}b/, '{2,4}', :greedy, :interval, 2, 4
27
- include_examples 'quantifier', /a{2,4}?b/, '{2,4}?', :reluctant, :interval, 2, 4
28
- include_examples 'quantifier', /a{2,4}+b/, '{2,4}+', :possessive, :interval, 2, 4
29
- include_examples 'quantifier', /a{2,}b/, '{2,}', :greedy, :interval, 2, -1
30
- include_examples 'quantifier', /a{2,}?b/, '{2,}?', :reluctant, :interval, 2, -1
31
- include_examples 'quantifier', /a{2,}+b/, '{2,}+', :possessive, :interval, 2, -1
32
- include_examples 'quantifier', /a{,3}b/, '{,3}', :greedy, :interval, 0, 3
33
- include_examples 'quantifier', /a{,3}?b/, '{,3}?', :reluctant, :interval, 0, 3
34
- include_examples 'quantifier', /a{,3}+b/, '{,3}+', :possessive, :interval, 0, 3
35
- include_examples 'quantifier', /a{4}b/, '{4}', :greedy, :interval, 4, 4
36
- include_examples 'quantifier', /a{4}?b/, '{4}?', :reluctant, :interval, 4, 4
37
- include_examples 'quantifier', /a{4}+b/, '{4}+', :possessive, :interval, 4, 4
38
-
39
- specify('mode-checking methods') do
40
- exp = RP.parse(/a??/).first
41
-
42
- expect(exp).to be_reluctant
43
- expect(exp).to be_lazy
44
- expect(exp).not_to be_greedy
45
- expect(exp).not_to be_possessive
46
- expect(exp.quantifier).to be_reluctant
47
- expect(exp.quantifier).to be_lazy
48
- expect(exp.quantifier).not_to be_greedy
49
- expect(exp.quantifier).not_to be_possessive
50
- end
51
- end
@@ -1,112 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe('Refcall parsing') do
4
- include_examples 'parse', /(abc)\1/,
5
- 1 => [:backref, :number, Backreference::Number, number: 1]
6
-
7
- include_examples 'parse', /(?<X>abc)\k<X>/,
8
- 1 => [:backref, :name_ref, Backreference::Name, name: 'X']
9
- include_examples 'parse', /(?<X>abc)\k'X'/,
10
- 1 => [:backref, :name_ref, Backreference::Name, name: 'X']
11
-
12
- include_examples 'parse', /(abc)\k<1>/,
13
- 1 => [:backref, :number_ref, Backreference::Number, number: 1]
14
- include_examples 'parse', /(abc)\k'1'/,
15
- 1 => [:backref, :number_ref, Backreference::Number, number: 1]
16
-
17
- include_examples 'parse', /(abc)\k<-1>/,
18
- 1 => [:backref, :number_rel_ref, Backreference::NumberRelative, number: -1]
19
- include_examples 'parse', /(abc)\k'-1'/,
20
- 1 => [:backref, :number_rel_ref, Backreference::NumberRelative, number: -1]
21
-
22
- include_examples 'parse', /(?<X>abc)\g<X>/,
23
- 1 => [:backref, :name_call, Backreference::NameCall, name: 'X']
24
- include_examples 'parse', /(?<X>abc)\g'X'/,
25
- 1 => [:backref, :name_call, Backreference::NameCall, name: 'X']
26
-
27
- include_examples 'parse', /(abc)\g<1>/,
28
- 1 => [:backref, :number_call, Backreference::NumberCall, number: 1]
29
- include_examples 'parse', /(abc)\g'1'/,
30
- 1 => [:backref, :number_call, Backreference::NumberCall, number: 1]
31
-
32
- include_examples 'parse', /(abc)\g<-1>/,
33
- 1 => [:backref, :number_rel_call, Backreference::NumberCallRelative, number: -1]
34
- include_examples 'parse', /(abc)\g'-1'/,
35
- 1 => [:backref, :number_rel_call, Backreference::NumberCallRelative, number: -1]
36
-
37
- include_examples 'parse', /\g<+1>(abc)/,
38
- 0 => [:backref, :number_rel_call, Backreference::NumberCallRelative, number: 1]
39
- include_examples 'parse', /\g'+1'(abc)/,
40
- 0 => [:backref, :number_rel_call, Backreference::NumberCallRelative, number: 1]
41
-
42
- include_examples 'parse', /(?<X>abc)\k<X-0>/,
43
- 1 => [:backref, :name_recursion_ref, Backreference::NameRecursionLevel,
44
- name: 'X', recursion_level: 0]
45
- include_examples 'parse', /(?<X>abc)\k'X-0'/,
46
- 1 => [:backref, :name_recursion_ref, Backreference::NameRecursionLevel,
47
- name: 'X', recursion_level: 0]
48
-
49
- include_examples 'parse', /(abc)\k<1-0>/,
50
- 1 => [:backref, :number_recursion_ref, Backreference::NumberRecursionLevel,
51
- number: 1, recursion_level: 0]
52
- include_examples 'parse', /(abc)\k'1-0'/,
53
- 1 => [:backref, :number_recursion_ref, Backreference::NumberRecursionLevel,
54
- number: 1, recursion_level: 0]
55
- include_examples 'parse', /(abc)\k'-1+0'/,
56
- 1 => [:backref, :number_recursion_ref, Backreference::NumberRecursionLevel,
57
- number: -1, recursion_level: 0]
58
- include_examples 'parse', /(abc)\k'1+1'/,
59
- 1 => [:backref, :number_recursion_ref, Backreference::NumberRecursionLevel,
60
- number: 1, recursion_level: 1]
61
- include_examples 'parse', /(abc)\k'1-1'/,
62
- 1 => [:backref, :number_recursion_ref, Backreference::NumberRecursionLevel,
63
- number: 1, recursion_level: -1]
64
-
65
- specify('parse backref effective_number') do
66
- root = RP.parse('(abc)(def)\\k<-1>(ghi)\\k<-3>\\k<-1>', 'ruby/1.9')
67
- exp1 = root[2]
68
- exp2 = root[4]
69
- exp3 = root[5]
70
-
71
- expect([exp1, exp2, exp3]).to all be_instance_of(Backreference::NumberRelative)
72
- expect(exp1.effective_number).to eq 2
73
- expect(exp2.effective_number).to eq 1
74
- expect(exp3.effective_number).to eq 3
75
- end
76
-
77
- specify('parse backref referenced_expression') do
78
- root = RP.parse('(abc)(def)\\k<-1>(ghi)\\k<-3>\\k<-1>', 'ruby/1.9')
79
- exp1 = root[2]
80
- exp2 = root[4]
81
- exp3 = root[5]
82
-
83
- expect([exp1, exp2, exp3]).to all be_instance_of(Backreference::NumberRelative)
84
- expect(exp1.referenced_expression.to_s).to eq '(def)'
85
- expect(exp2.referenced_expression.to_s).to eq '(abc)'
86
- expect(exp3.referenced_expression.to_s).to eq '(ghi)'
87
- end
88
-
89
- specify('parse backref call effective_number') do
90
- root = RP.parse('\\g<+1>(abc)\\g<+2>(def)(ghi)\\g<-2>', 'ruby/1.9')
91
- exp1 = root[0]
92
- exp2 = root[2]
93
- exp3 = root[5]
94
-
95
- expect([exp1, exp2, exp3]).to all be_instance_of(Backreference::NumberCallRelative)
96
- expect(exp1.effective_number).to eq 1
97
- expect(exp2.effective_number).to eq 3
98
- expect(exp3.effective_number).to eq 2
99
- end
100
-
101
- specify('parse backref call referenced_expression') do
102
- root = RP.parse('\\g<+1>(abc)\\g<+2>(def)(ghi)\\g<-2>', 'ruby/1.9')
103
- exp1 = root[0]
104
- exp2 = root[2]
105
- exp3 = root[5]
106
-
107
- expect([exp1, exp2, exp3]).to all be_instance_of(Backreference::NumberCallRelative)
108
- expect(exp1.referenced_expression.to_s).to eq '(abc)'
109
- expect(exp2.referenced_expression.to_s).to eq '(ghi)'
110
- expect(exp3.referenced_expression.to_s).to eq '(def)'
111
- end
112
- end
@@ -1,127 +0,0 @@
1
- require 'spec_helper'
2
-
3
- # edge cases with `...-&&...` and `...&&-...` are checked in test_ranges.rb
4
-
5
- RSpec.describe('CharacterSet::Intersection parsing') do
6
- specify('parse set intersection') do
7
- root = RP.parse('[a&&z]')
8
- set = root[0]
9
- ints = set[0]
10
-
11
- expect(set.count).to eq 1
12
- expect(ints).to be_instance_of(CharacterSet::Intersection)
13
- expect(ints.count).to eq 2
14
-
15
- seq1, seq2 = ints.expressions
16
- expect(seq1).to be_instance_of(CharacterSet::IntersectedSequence)
17
- expect(seq1.count).to eq 1
18
- expect(seq1.first.to_s).to eq 'a'
19
- expect(seq1.first).to be_instance_of(Literal)
20
- expect(seq2).to be_instance_of(CharacterSet::IntersectedSequence)
21
- expect(seq2.count).to eq 1
22
- expect(seq2.first.to_s).to eq 'z'
23
- expect(seq2.first).to be_instance_of(Literal)
24
-
25
- expect(set).not_to match 'a'
26
- expect(set).not_to match '&'
27
- expect(set).not_to match 'z'
28
- end
29
-
30
- specify('parse set intersection range and subset') do
31
- root = RP.parse('[a-z&&[^a]]')
32
- set = root[0]
33
- ints = set[0]
34
-
35
- expect(set.count).to eq 1
36
- expect(ints).to be_instance_of(CharacterSet::Intersection)
37
- expect(ints.count).to eq 2
38
-
39
- seq1, seq2 = ints.expressions
40
- expect(seq1).to be_instance_of(CharacterSet::IntersectedSequence)
41
- expect(seq1.count).to eq 1
42
- expect(seq1.first.to_s).to eq 'a-z'
43
- expect(seq1.first).to be_instance_of(CharacterSet::Range)
44
- expect(seq2).to be_instance_of(CharacterSet::IntersectedSequence)
45
- expect(seq2.count).to eq 1
46
- expect(seq2.first.to_s).to eq '[^a]'
47
- expect(seq2.first).to be_instance_of(CharacterSet)
48
-
49
- expect(set).not_to match 'a'
50
- expect(set).not_to match '&'
51
- expect(set).to match 'b'
52
- end
53
-
54
- specify('parse set intersection trailing range') do
55
- root = RP.parse('[a&&a-z]')
56
- set = root[0]
57
- ints = set[0]
58
-
59
- expect(set.count).to eq 1
60
- expect(ints).to be_instance_of(CharacterSet::Intersection)
61
- expect(ints.count).to eq 2
62
-
63
- seq1, seq2 = ints.expressions
64
- expect(seq1).to be_instance_of(CharacterSet::IntersectedSequence)
65
- expect(seq1.count).to eq 1
66
- expect(seq1.first.to_s).to eq 'a'
67
- expect(seq1.first).to be_instance_of(Literal)
68
- expect(seq2).to be_instance_of(CharacterSet::IntersectedSequence)
69
- expect(seq2.count).to eq 1
70
- expect(seq2.first.to_s).to eq 'a-z'
71
- expect(seq2.first).to be_instance_of(CharacterSet::Range)
72
-
73
- expect(set).to match 'a'
74
- expect(set).not_to match '&'
75
- expect(set).not_to match 'b'
76
- end
77
-
78
- specify('parse set intersection type') do
79
- root = RP.parse('[a&&\\w]')
80
- set = root[0]
81
- ints = set[0]
82
-
83
- expect(set.count).to eq 1
84
- expect(ints).to be_instance_of(CharacterSet::Intersection)
85
- expect(ints.count).to eq 2
86
-
87
- seq1, seq2 = ints.expressions
88
- expect(seq1).to be_instance_of(CharacterSet::IntersectedSequence)
89
- expect(seq1.count).to eq 1
90
- expect(seq1.first.to_s).to eq 'a'
91
- expect(seq1.first).to be_instance_of(Literal)
92
- expect(seq2).to be_instance_of(CharacterSet::IntersectedSequence)
93
- expect(seq2.count).to eq 1
94
- expect(seq2.first.to_s).to eq '\\w'
95
- expect(seq2.first).to be_instance_of(CharacterType::Word)
96
-
97
- expect(set).to match 'a'
98
- expect(set).not_to match '&'
99
- expect(set).not_to match 'b'
100
- end
101
-
102
- specify('parse set intersection multipart') do
103
- root = RP.parse('[\\h&&\\w&&efg]')
104
- set = root[0]
105
- ints = set[0]
106
-
107
- expect(set.count).to eq 1
108
- expect(ints).to be_instance_of(CharacterSet::Intersection)
109
- expect(ints.count).to eq 3
110
-
111
- seq1, seq2, seq3 = ints.expressions
112
- expect(seq1).to be_instance_of(CharacterSet::IntersectedSequence)
113
- expect(seq1.count).to eq 1
114
- expect(seq1.first.to_s).to eq '\\h'
115
- expect(seq2).to be_instance_of(CharacterSet::IntersectedSequence)
116
- expect(seq2.count).to eq 1
117
- expect(seq2.first.to_s).to eq '\\w'
118
- expect(seq3).to be_instance_of(CharacterSet::IntersectedSequence)
119
- expect(seq3.count).to eq 3
120
- expect(seq3.to_s).to eq 'efg'
121
-
122
- expect(set).to match 'e'
123
- expect(set).to match 'f'
124
- expect(set).not_to match 'a'
125
- expect(set).not_to match 'g'
126
- end
127
- end
@@ -1,111 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe('CharacterSet::Range parsing') do
4
- specify('parse set range') do
5
- root = RP.parse('[a-z]')
6
- set = root[0]
7
- range = set[0]
8
-
9
- expect(set.count).to eq 1
10
- expect(range).to be_instance_of(CharacterSet::Range)
11
- expect(range.count).to eq 2
12
- expect(range.first.to_s).to eq 'a'
13
- expect(range.first).to be_instance_of(Literal)
14
- expect(range.last.to_s).to eq 'z'
15
- expect(range.last).to be_instance_of(Literal)
16
- expect(set).to match 'm'
17
- end
18
-
19
- specify('parse set range hex') do
20
- root = RP.parse('[\\x00-\\x99]')
21
- set = root[0]
22
- range = set[0]
23
-
24
- expect(set.count).to eq 1
25
- expect(range).to be_instance_of(CharacterSet::Range)
26
- expect(range.count).to eq 2
27
- expect(range.first.to_s).to eq '\\x00'
28
- expect(range.first).to be_instance_of(EscapeSequence::Hex)
29
- expect(range.last.to_s).to eq '\\x99'
30
- expect(range.last).to be_instance_of(EscapeSequence::Hex)
31
- expect(set).to match '\\x50'
32
- end
33
-
34
- specify('parse set range unicode') do
35
- root = RP.parse('[\\u{40 42}-\\u1234]')
36
- set = root[0]
37
- range = set[0]
38
-
39
- expect(set.count).to eq 1
40
- expect(range).to be_instance_of(CharacterSet::Range)
41
- expect(range.count).to eq 2
42
- expect(range.first.to_s).to eq '\\u{40 42}'
43
- expect(range.first).to be_instance_of(EscapeSequence::CodepointList)
44
- expect(range.last.to_s).to eq '\\u1234'
45
- expect(range.last).to be_instance_of(EscapeSequence::Codepoint)
46
- expect(set).to match '\\u600'
47
- end
48
-
49
- specify('parse set range edge case leading dash') do
50
- root = RP.parse('[--z]')
51
- set = root[0]
52
- range = set[0]
53
-
54
- expect(set.count).to eq 1
55
- expect(range.count).to eq 2
56
- expect(set).to match 'a'
57
- end
58
-
59
- specify('parse set range edge case trailing dash') do
60
- root = RP.parse('[!--]')
61
- set = root[0]
62
- range = set[0]
63
-
64
- expect(set.count).to eq 1
65
- expect(range.count).to eq 2
66
- expect(set).to match '$'
67
- end
68
-
69
- specify('parse set range edge case leading negate') do
70
- root = RP.parse('[^-z]')
71
- set = root[0]
72
-
73
- expect(set.count).to eq 2
74
- expect(set).to match 'a'
75
- expect(set).not_to match 'z'
76
- end
77
-
78
- specify('parse set range edge case trailing negate') do
79
- root = RP.parse('[!-^]')
80
- set = root[0]
81
- range = set[0]
82
-
83
- expect(set.count).to eq 1
84
- expect(range.count).to eq 2
85
- expect(set).to match '$'
86
- end
87
-
88
- specify('parse set range edge case leading intersection') do
89
- root = RP.parse('[[\\-ab]&&-bc]')
90
- set = root[0]
91
-
92
- expect(set.count).to eq 1
93
- expect(set.first.last.to_s).to eq '-bc'
94
- expect(set).to match '-'
95
- expect(set).to match 'b'
96
- expect(set).not_to match 'a'
97
- expect(set).not_to match 'c'
98
- end
99
-
100
- specify('parse set range edge case trailing intersection') do
101
- root = RP.parse('[bc-&&[\\-ab]]')
102
- set = root[0]
103
-
104
- expect(set.count).to eq 1
105
- expect(set.first.first.to_s).to eq 'bc-'
106
- expect(set).to match '-'
107
- expect(set).to match 'b'
108
- expect(set).not_to match 'a'
109
- expect(set).not_to match 'c'
110
- end
111
- end
@@ -1,178 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe('CharacterSet parsing') do
4
- specify('parse set basic') do
5
- root = RP.parse('[ab]+')
6
- exp = root[0]
7
-
8
- expect(exp).to be_instance_of(CharacterSet)
9
- expect(exp.count).to eq 2
10
-
11
- expect(exp[0]).to be_instance_of(Literal)
12
- expect(exp[0].text).to eq 'a'
13
- expect(exp[1]).to be_instance_of(Literal)
14
- expect(exp[1].text).to eq 'b'
15
-
16
- expect(exp).to be_quantified
17
- expect(exp.quantifier.min).to eq 1
18
- expect(exp.quantifier.max).to eq(-1)
19
- end
20
-
21
- specify('parse set char type') do
22
- root = RP.parse('[a\\dc]')
23
- exp = root[0]
24
-
25
- expect(exp).to be_instance_of(CharacterSet)
26
- expect(exp.count).to eq 3
27
-
28
- expect(exp[1]).to be_instance_of(CharacterType::Digit)
29
- expect(exp[1].text).to eq '\\d'
30
- end
31
-
32
- specify('parse set escape sequence backspace') do
33
- root = RP.parse('[a\\bc]')
34
- exp = root[0]
35
-
36
- expect(exp).to be_instance_of(CharacterSet)
37
- expect(exp.count).to eq 3
38
-
39
- expect(exp[1]).to be_instance_of(EscapeSequence::Backspace)
40
- expect(exp[1].text).to eq '\\b'
41
-
42
- expect(exp).to match 'a'
43
- expect(exp).to match "\b"
44
- expect(exp).not_to match 'b'
45
- expect(exp).to match 'c'
46
- end
47
-
48
- specify('parse set escape sequence hex') do
49
- root = RP.parse('[a\\x20c]', :any)
50
- exp = root[0]
51
-
52
- expect(exp).to be_instance_of(CharacterSet)
53
- expect(exp.count).to eq 3
54
-
55
- expect(exp[1]).to be_instance_of(EscapeSequence::Hex)
56
- expect(exp[1].text).to eq '\\x20'
57
- end
58
-
59
- specify('parse set escape sequence codepoint') do
60
- root = RP.parse('[a\\u0640]')
61
- exp = root[0]
62
-
63
- expect(exp).to be_instance_of(CharacterSet)
64
- expect(exp.count).to eq 2
65
-
66
- expect(exp[1]).to be_instance_of(EscapeSequence::Codepoint)
67
- expect(exp[1].text).to eq '\\u0640'
68
- end
69
-
70
- specify('parse set escape sequence codepoint list') do
71
- root = RP.parse('[a\\u{41 1F60D}]')
72
- exp = root[0]
73
-
74
- expect(exp).to be_instance_of(CharacterSet)
75
- expect(exp.count).to eq 2
76
-
77
- expect(exp[1]).to be_instance_of(EscapeSequence::CodepointList)
78
- expect(exp[1].text).to eq '\\u{41 1F60D}'
79
- end
80
-
81
- specify('parse set posix class') do
82
- root = RP.parse('[[:digit:][:^lower:]]+')
83
- exp = root[0]
84
-
85
- expect(exp).to be_instance_of(CharacterSet)
86
- expect(exp.count).to eq 2
87
-
88
- expect(exp[0]).to be_instance_of(PosixClass)
89
- expect(exp[0].text).to eq '[:digit:]'
90
- expect(exp[1]).to be_instance_of(PosixClass)
91
- expect(exp[1].text).to eq '[:^lower:]'
92
- end
93
-
94
- specify('parse set nesting') do
95
- root = RP.parse('[a[b[c]d]e]')
96
-
97
- exp = root[0]
98
- expect(exp).to be_instance_of(CharacterSet)
99
- expect(exp.count).to eq 3
100
- expect(exp[0]).to be_instance_of(Literal)
101
- expect(exp[2]).to be_instance_of(Literal)
102
-
103
- subset1 = exp[1]
104
- expect(subset1).to be_instance_of(CharacterSet)
105
- expect(subset1.count).to eq 3
106
- expect(subset1[0]).to be_instance_of(Literal)
107
- expect(subset1[2]).to be_instance_of(Literal)
108
-
109
- subset2 = subset1[1]
110
- expect(subset2).to be_instance_of(CharacterSet)
111
- expect(subset2.count).to eq 1
112
- expect(subset2[0]).to be_instance_of(Literal)
113
- end
114
-
115
- specify('parse set nesting negative') do
116
- root = RP.parse('[a[^b[c]]]')
117
- exp = root[0]
118
-
119
- expect(exp).to be_instance_of(CharacterSet)
120
- expect(exp.count).to eq 2
121
- expect(exp[0]).to be_instance_of(Literal)
122
- expect(exp).not_to be_negative
123
-
124
- subset1 = exp[1]
125
- expect(subset1).to be_instance_of(CharacterSet)
126
- expect(subset1.count).to eq 2
127
- expect(subset1[0]).to be_instance_of(Literal)
128
- expect(subset1).to be_negative
129
-
130
- subset2 = subset1[1]
131
- expect(subset2).to be_instance_of(CharacterSet)
132
- expect(subset2.count).to eq 1
133
- expect(subset2[0]).to be_instance_of(Literal)
134
- expect(subset2).not_to be_negative
135
- end
136
-
137
- specify('parse set nesting #to_s') do
138
- pattern = '[a[b[^c]]]'
139
- root = RP.parse(pattern)
140
-
141
- expect(root.to_s).to eq pattern
142
- end
143
-
144
- specify('parse set literals are not merged') do
145
- root = RP.parse("[#{('a' * 10)}]")
146
- exp = root[0]
147
-
148
- expect(exp.count).to eq 10
149
- end
150
-
151
- specify('parse set whitespace is not merged') do
152
- root = RP.parse("[#{(' ' * 10)}]")
153
- exp = root[0]
154
-
155
- expect(exp.count).to eq 10
156
- end
157
-
158
- specify('parse set whitespace is not merged in x mode') do
159
- root = RP.parse("(?x)[#{(' ' * 10)}]")
160
- exp = root[1]
161
-
162
- expect(exp.count).to eq 10
163
- end
164
-
165
- specify('parse set collating sequence') do
166
- root = RP.parse('[a[.span-ll.]h]', :any)
167
- exp = root[0]
168
-
169
- expect(exp[1].to_s).to eq '[.span-ll.]'
170
- end
171
-
172
- specify('parse set character equivalents') do
173
- root = RP.parse('[a[=e=]h]', :any)
174
- exp = root[0]
175
-
176
- expect(exp[1].to_s).to eq '[=e=]'
177
- end
178
- end