regexp_parser 2.2.0 → 2.2.1

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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +14 -2
  3. data/LICENSE +1 -1
  4. data/README.md +2 -2
  5. data/Rakefile +5 -8
  6. data/lib/regexp_parser/expression/classes/escape_sequence.rb +12 -7
  7. data/lib/regexp_parser/expression/methods/strfregexp.rb +1 -1
  8. data/lib/regexp_parser/scanner/properties/long.csv +604 -0
  9. data/lib/regexp_parser/scanner/properties/short.csv +242 -0
  10. data/lib/regexp_parser/scanner/scanner.rl +6 -4
  11. data/lib/regexp_parser/scanner.rb +126 -124
  12. data/lib/regexp_parser/syntax/base.rb +3 -5
  13. data/lib/regexp_parser/syntax/token/backreference.rb +7 -2
  14. data/lib/regexp_parser/syntax/versions/1.8.6.rb +2 -2
  15. data/lib/regexp_parser/syntax/versions/1.9.1.rb +1 -1
  16. data/lib/regexp_parser/version.rb +1 -1
  17. data/regexp_parser.gemspec +20 -22
  18. metadata +11 -143
  19. data/lib/regexp_parser/scanner/properties/long.yml +0 -607
  20. data/lib/regexp_parser/scanner/properties/short.yml +0 -245
  21. data/spec/expression/base_spec.rb +0 -104
  22. data/spec/expression/clone_spec.rb +0 -152
  23. data/spec/expression/conditional_spec.rb +0 -89
  24. data/spec/expression/free_space_spec.rb +0 -27
  25. data/spec/expression/methods/match_length_spec.rb +0 -161
  26. data/spec/expression/methods/match_spec.rb +0 -25
  27. data/spec/expression/methods/strfregexp_spec.rb +0 -224
  28. data/spec/expression/methods/tests_spec.rb +0 -99
  29. data/spec/expression/methods/traverse_spec.rb +0 -161
  30. data/spec/expression/options_spec.rb +0 -128
  31. data/spec/expression/subexpression_spec.rb +0 -50
  32. data/spec/expression/to_h_spec.rb +0 -26
  33. data/spec/expression/to_s_spec.rb +0 -108
  34. data/spec/lexer/all_spec.rb +0 -22
  35. data/spec/lexer/conditionals_spec.rb +0 -53
  36. data/spec/lexer/delimiters_spec.rb +0 -68
  37. data/spec/lexer/escapes_spec.rb +0 -14
  38. data/spec/lexer/keep_spec.rb +0 -10
  39. data/spec/lexer/literals_spec.rb +0 -64
  40. data/spec/lexer/nesting_spec.rb +0 -99
  41. data/spec/lexer/refcalls_spec.rb +0 -60
  42. data/spec/parser/all_spec.rb +0 -43
  43. data/spec/parser/alternation_spec.rb +0 -88
  44. data/spec/parser/anchors_spec.rb +0 -17
  45. data/spec/parser/conditionals_spec.rb +0 -179
  46. data/spec/parser/errors_spec.rb +0 -30
  47. data/spec/parser/escapes_spec.rb +0 -133
  48. data/spec/parser/free_space_spec.rb +0 -130
  49. data/spec/parser/groups_spec.rb +0 -108
  50. data/spec/parser/keep_spec.rb +0 -6
  51. data/spec/parser/options_spec.rb +0 -28
  52. data/spec/parser/posix_classes_spec.rb +0 -8
  53. data/spec/parser/properties_spec.rb +0 -117
  54. data/spec/parser/quantifiers_spec.rb +0 -68
  55. data/spec/parser/refcalls_spec.rb +0 -117
  56. data/spec/parser/set/intersections_spec.rb +0 -127
  57. data/spec/parser/set/ranges_spec.rb +0 -121
  58. data/spec/parser/sets_spec.rb +0 -178
  59. data/spec/parser/types_spec.rb +0 -18
  60. data/spec/scanner/all_spec.rb +0 -18
  61. data/spec/scanner/anchors_spec.rb +0 -21
  62. data/spec/scanner/conditionals_spec.rb +0 -128
  63. data/spec/scanner/delimiters_spec.rb +0 -52
  64. data/spec/scanner/errors_spec.rb +0 -67
  65. data/spec/scanner/escapes_spec.rb +0 -73
  66. data/spec/scanner/free_space_spec.rb +0 -165
  67. data/spec/scanner/groups_spec.rb +0 -61
  68. data/spec/scanner/keep_spec.rb +0 -10
  69. data/spec/scanner/literals_spec.rb +0 -39
  70. data/spec/scanner/meta_spec.rb +0 -18
  71. data/spec/scanner/options_spec.rb +0 -36
  72. data/spec/scanner/properties_spec.rb +0 -64
  73. data/spec/scanner/quantifiers_spec.rb +0 -25
  74. data/spec/scanner/refcalls_spec.rb +0 -55
  75. data/spec/scanner/sets_spec.rb +0 -151
  76. data/spec/scanner/types_spec.rb +0 -14
  77. data/spec/spec_helper.rb +0 -28
  78. data/spec/support/capturing_stderr.rb +0 -9
  79. data/spec/support/shared_examples.rb +0 -77
  80. data/spec/syntax/syntax_spec.rb +0 -48
  81. data/spec/syntax/syntax_token_map_spec.rb +0 -23
  82. data/spec/syntax/versions/1.8.6_spec.rb +0 -17
  83. data/spec/syntax/versions/1.9.1_spec.rb +0 -10
  84. data/spec/syntax/versions/1.9.3_spec.rb +0 -9
  85. data/spec/syntax/versions/2.0.0_spec.rb +0 -13
  86. data/spec/syntax/versions/2.2.0_spec.rb +0 -9
  87. data/spec/syntax/versions/aliases_spec.rb +0 -38
  88. data/spec/token/token_spec.rb +0 -85
@@ -1,73 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe('Escape scanning') do
4
- include_examples 'scan', /c\at/, 1 => [:escape, :bell, '\a', 1, 3]
5
-
6
- # not an escape outside a character set
7
- include_examples 'scan', /c\bt/, 1 => [:anchor, :word_boundary, '\b', 1, 3]
8
-
9
- include_examples 'scan', /c\ft/, 1 => [:escape, :form_feed, '\f', 1, 3]
10
- include_examples 'scan', /c\nt/, 1 => [:escape, :newline, '\n', 1, 3]
11
- include_examples 'scan', /c\tt/, 1 => [:escape, :tab, '\t', 1, 3]
12
- include_examples 'scan', /c\vt/, 1 => [:escape, :vertical_tab, '\v', 1, 3]
13
-
14
- # ineffectual literal escapes
15
- # these cause "Unknown escape" warnings in Ruby for ascii chars,
16
- # and simply drop the backslash for non-ascii chars (/\ü/.inspect == '/ü/').
17
- # In terms of matching, Ruby treats them both like non-escaped literals.
18
- include_examples 'scan', 'c\qt', 1 => [:escape, :literal, '\q', 1, 3]
19
- include_examples 'scan', 'a\üc', 1 => [:escape, :literal, '\ü', 1, 3]
20
- include_examples 'scan', 'a\😋c', 1 => [:escape, :literal, '\😋', 1, 3]
21
-
22
- # these incomplete ref/call sequences are treated as literal escapes by Ruby
23
- include_examples 'scan', 'c\gt', 1 => [:escape, :literal, '\g', 1, 3]
24
- include_examples 'scan', 'c\kt', 1 => [:escape, :literal, '\k', 1, 3]
25
-
26
- include_examples 'scan', 'a\012c', 1 => [:escape, :octal, '\012', 1, 5]
27
- include_examples 'scan', 'a\0124', 1 => [:escape, :octal, '\012', 1, 5]
28
- include_examples 'scan', '\712+7', 0 => [:escape, :octal, '\712', 0, 4]
29
-
30
- include_examples 'scan', 'a\xA', 1 => [:escape, :hex, '\xA', 1, 4]
31
- include_examples 'scan', 'a\x24c', 1 => [:escape, :hex, '\x24', 1, 5]
32
- include_examples 'scan', 'a\x0640c', 1 => [:escape, :hex, '\x06', 1, 5]
33
-
34
- include_examples 'scan', 'a\u0640c', 1 => [:escape, :codepoint, '\u0640', 1, 7]
35
- include_examples 'scan', 'a\u{640 0641}c', 1 => [:escape, :codepoint_list, '\u{640 0641}', 1, 13]
36
- include_examples 'scan', 'a\u{10FFFF}c', 1 => [:escape, :codepoint_list, '\u{10FFFF}', 1, 11]
37
-
38
- include_examples 'scan', 'ab\\\xcd', 1 => [:escape, :backslash, '\\\\', 2, 4]
39
- include_examples 'scan', 'ab\\\0cd', 1 => [:escape, :backslash, '\\\\', 2, 4]
40
- include_examples 'scan', 'ab\\\Kcd', 1 => [:escape, :backslash, '\\\\', 2, 4]
41
-
42
- include_examples 'scan', 'ab\^cd', 1 => [:escape, :bol, '\^', 2, 4]
43
- include_examples 'scan', 'ab\$cd', 1 => [:escape, :eol, '\$', 2, 4]
44
- include_examples 'scan', 'ab\[cd', 1 => [:escape, :set_open, '\[', 2, 4]
45
-
46
- # Meta/control espaces
47
- #
48
- # After the following fix in Ruby 3.1, a Regexp#source containing meta/control
49
- # escapes can only be set with the Regexp::new constructor.
50
- # In Regexp literals, these escapes are now pre-processed to hex escapes.
51
- #
52
- # https://github.com/ruby/ruby/commit/11ae581a4a7f5d5f5ec6378872eab8f25381b1b9
53
- n = ->(regexp_body){ Regexp.new(regexp_body.force_encoding('ascii-8bit'), 'n') }
54
-
55
- include_examples 'scan', 'a\cBc', 1 => [:escape, :control, '\cB', 1, 4]
56
- include_examples 'scan', 'a\c^c', 1 => [:escape, :control, '\c^', 1, 4]
57
- include_examples 'scan', 'a\c\n', 1 => [:escape, :control, '\c\n', 1, 5]
58
- include_examples 'scan', 'a\c\\\\b', 1 => [:escape, :control, '\c\\\\', 1, 5]
59
- include_examples 'scan', 'a\C-bc', 1 => [:escape, :control, '\C-b', 1, 5]
60
- include_examples 'scan', 'a\C-^b', 1 => [:escape, :control, '\C-^', 1, 5]
61
- include_examples 'scan', 'a\C-\nb', 1 => [:escape, :control, '\C-\n', 1, 6]
62
- include_examples 'scan', 'a\C-\\\\b', 1 => [:escape, :control, '\C-\\\\', 1, 6]
63
- include_examples 'scan', n.('a\c\M-Bc'), 1 => [:escape, :control, '\c\M-B', 1, 7]
64
- include_examples 'scan', n.('a\C-\M-Bc'), 1 => [:escape, :control, '\C-\M-B', 1, 8]
65
-
66
- include_examples 'scan', n.('a\M-Bc'), 1 => [:escape, :meta_sequence, '\M-B', 1, 5]
67
- include_examples 'scan', n.('a\M-\cBc'), 1 => [:escape, :meta_sequence, '\M-\cB', 1, 7]
68
- include_examples 'scan', n.('a\M-\c^'), 1 => [:escape, :meta_sequence, '\M-\c^', 1, 7]
69
- include_examples 'scan', n.('a\M-\c\n'), 1 => [:escape, :meta_sequence, '\M-\c\n', 1, 8]
70
- include_examples 'scan', n.('a\M-\c\\\\'), 1 => [:escape, :meta_sequence, '\M-\c\\\\', 1, 8]
71
- include_examples 'scan', n.('a\M-\C-Bc'), 1 => [:escape, :meta_sequence, '\M-\C-B', 1, 8]
72
- include_examples 'scan', n.('a\M-\C-\\\\'), 1 => [:escape, :meta_sequence, '\M-\C-\\\\', 1, 9]
73
- end
@@ -1,165 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe('FreeSpace scanning') do
4
- describe('scan free space tokens') do
5
- let(:tokens) { RS.scan(/
6
- a
7
- b ? c *
8
- d {2,3}
9
- e + | f +
10
- /x) }
11
-
12
- 0.upto(24).select(&:even?).each do |i|
13
- it "scans #{i} as free space" do
14
- expect(tokens[i][0]).to eq :free_space
15
- expect(tokens[i][1]).to eq :whitespace
16
- end
17
- end
18
- 0.upto(24).reject(&:even?).each do |i|
19
- it "does not scan #{i} as free space" do
20
- expect(tokens[i][0]).not_to eq :free_space
21
- expect(tokens[i][1]).not_to eq :whitespace
22
- end
23
- end
24
-
25
- it 'sets the correct text' do
26
- [0, 2, 10, 14].each { |i| expect(tokens[i][2]).to eq "\n " }
27
- [4, 6, 8, 12].each { |i| expect(tokens[i][2]).to eq ' ' }
28
- end
29
- end
30
-
31
- describe('scan free space comments') do
32
- include_examples 'scan', /
33
- a + # A + comment
34
- b ? # B ? comment
35
- c {2,3} # C {2,3} comment
36
- d + | e + # D|E comment
37
- /x,
38
- 5 => [:free_space, :comment, "# A + comment\n", 11, 25],
39
- 11 => [:free_space, :comment, "# B ? comment\n", 37, 51],
40
- 17 => [:free_space, :comment, "# C {2,3} comment\n", 66, 84],
41
- 29 => [:free_space, :comment, "# D|E comment\n", 100, 114]
42
-
43
- # single line / no trailing newline (c.f. issue #66)
44
- include_examples 'scan', /a # b/x,
45
- 0 => [:literal, :literal, 'a', 0, 1],
46
- 1 => [:free_space, :whitespace, ' ', 1, 2],
47
- 2 => [:free_space, :comment, "# b", 2, 5]
48
-
49
- # without spaces (c.f. issue #66)
50
- include_examples 'scan', /a#b/x,
51
- 0 => [:literal, :literal, 'a', 0, 1],
52
- 1 => [:free_space, :comment, "#b", 1, 3]
53
- end
54
-
55
- describe('scan free space inlined') do
56
- include_examples 'scan', /a b(?x:c d e)f g/,
57
- 0 => [:literal, :literal, 'a b', 0, 3],
58
- 1 => [:group, :options, '(?x:', 3, 7],
59
- 2 => [:literal, :literal, 'c', 7, 8],
60
- 3 => [:free_space, :whitespace, ' ', 8, 9],
61
- 4 => [:literal, :literal, 'd', 9, 10],
62
- 5 => [:free_space, :whitespace, ' ', 10, 11],
63
- 6 => [:literal, :literal, 'e', 11, 12],
64
- 7 => [:group, :close, ')', 12, 13],
65
- 8 => [:literal, :literal, 'f g', 13, 16]
66
- end
67
-
68
- describe('scan free space nested') do
69
- include_examples 'scan', /a b(?x:c d(?-x:e f)g h)i j/,
70
- 0 => [:literal, :literal, 'a b', 0, 3],
71
- 1 => [:group, :options, '(?x:', 3, 7],
72
- 2 => [:literal, :literal, 'c', 7, 8],
73
- 3 => [:free_space, :whitespace, ' ', 8, 9],
74
- 4 => [:literal, :literal, 'd', 9, 10],
75
- 5 => [:group, :options, '(?-x:', 10, 15],
76
- 6 => [:literal, :literal, 'e f', 15, 18],
77
- 7 => [:group, :close, ')', 18, 19],
78
- 8 => [:literal, :literal, 'g', 19, 20],
79
- 9 => [:free_space, :whitespace, ' ', 20, 21],
80
- 10 => [:literal, :literal, 'h', 21, 22],
81
- 11 => [:group, :close, ')', 22, 23],
82
- 12 => [:literal, :literal, 'i j', 23, 26]
83
- end
84
-
85
- describe('scan free space nested groups') do
86
- include_examples 'scan', /(a (b(?x: (c d) (?-x:(e f) )g) h)i j)/,
87
- 0 => [:group, :capture, '(', 0, 1],
88
- 1 => [:literal, :literal, 'a ', 1, 3],
89
- 2 => [:group, :capture, '(', 3, 4],
90
- 3 => [:literal, :literal, 'b', 4, 5],
91
- 4 => [:group, :options, '(?x:', 5, 9],
92
- 5 => [:free_space, :whitespace, ' ', 9, 10],
93
- 6 => [:group, :capture, '(', 10, 11],
94
- 7 => [:literal, :literal, 'c', 11, 12],
95
- 8 => [:free_space, :whitespace, ' ', 12, 13],
96
- 9 => [:literal, :literal, 'd', 13, 14],
97
- 10 => [:group, :close, ')', 14, 15],
98
- 11 => [:free_space, :whitespace, ' ', 15, 16],
99
- 12 => [:group, :options, '(?-x:', 16, 21],
100
- 13 => [:group, :capture, '(', 21, 22],
101
- 14 => [:literal, :literal, 'e f', 22, 25],
102
- 15 => [:group, :close, ')', 25, 26],
103
- 16 => [:literal, :literal, ' ', 26, 27],
104
- 17 => [:group, :close, ')', 27, 28],
105
- 18 => [:literal, :literal, 'g', 28, 29],
106
- 19 => [:group, :close, ')', 29, 30],
107
- 20 => [:literal, :literal, ' h', 30, 32],
108
- 21 => [:group, :close, ')', 32, 33],
109
- 22 => [:literal, :literal, 'i j', 33, 36],
110
- 23 => [:group, :close, ')', 36, 37]
111
- end
112
-
113
- describe('scan free space switch groups') do
114
- include_examples 'scan', /(a (b((?x) (c d) ((?-x)(e f) )g) h)i j)/,
115
- 0 => [:group, :capture, '(', 0, 1],
116
- 1 => [:literal, :literal, 'a ', 1, 3],
117
- 2 => [:group, :capture, '(', 3, 4],
118
- 3 => [:literal, :literal, 'b', 4, 5],
119
- 4 => [:group, :capture, '(', 5, 6],
120
- 5 => [:group, :options_switch, '(?x', 6, 9],
121
- 6 => [:group, :close, ')', 9, 10],
122
- 7 => [:free_space, :whitespace, ' ', 10, 11],
123
- 8 => [:group, :capture, '(', 11, 12],
124
- 9 => [:literal, :literal, 'c', 12, 13],
125
- 10 => [:free_space, :whitespace, ' ', 13, 14],
126
- 11 => [:literal, :literal, 'd', 14, 15],
127
- 12 => [:group, :close, ')', 15, 16],
128
- 13 => [:free_space, :whitespace, ' ', 16, 17],
129
- 14 => [:group, :capture, '(', 17, 18],
130
- 15 => [:group, :options_switch, '(?-x', 18, 22],
131
- 16 => [:group, :close, ')', 22, 23],
132
- 17 => [:group, :capture, '(', 23, 24],
133
- 18 => [:literal, :literal, 'e f', 24, 27],
134
- 19 => [:group, :close, ')', 27, 28],
135
- 20 => [:literal, :literal, ' ', 28, 29],
136
- 21 => [:group, :close, ')', 29, 30],
137
- 22 => [:literal, :literal, 'g', 30, 31],
138
- 23 => [:group, :close, ')', 31, 32],
139
- 24 => [:literal, :literal, ' h', 32, 34],
140
- 25 => [:group, :close, ')', 34, 35],
141
- 26 => [:literal, :literal, 'i j', 35, 38],
142
- 27 => [:group, :close, ')', 38, 39]
143
- end
144
-
145
- describe('scanning `#` in regular (non-x mode)') do # c.f. issue 70
146
- include_examples 'scan', /a#bcd/,
147
- 0 => [:literal, :literal, 'a#bcd', 0, 5]
148
- include_examples 'scan', /a # bcd/,
149
- 0 => [:literal, :literal, 'a # bcd', 0, 7]
150
-
151
- include_examples 'scan', /a#\d/,
152
- 0 => [:literal, :literal, 'a#', 0, 2],
153
- 1 => [:type, :digit, '\d', 2, 4]
154
- include_examples 'scan', /a # \d/,
155
- 0 => [:literal, :literal, 'a # ', 0, 4],
156
- 1 => [:type, :digit, '\d', 4, 6]
157
-
158
- include_examples 'scan', /a#()/,
159
- 0 => [:literal, :literal, 'a#', 0, 2],
160
- 1 => [:group, :capture, '(', 2, 3]
161
- include_examples 'scan', /a # ()/,
162
- 0 => [:literal, :literal, 'a # ', 0, 4],
163
- 1 => [:group, :capture, '(', 4, 5]
164
- end
165
- end
@@ -1,61 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe('Group scanning') do
4
- # Group types
5
- include_examples 'scan', '(?>abc)', 0 => [:group, :atomic, '(?>', 0, 3]
6
- include_examples 'scan', '(abc)', 0 => [:group, :capture, '(', 0, 1]
7
-
8
- # Named groups
9
- # only names that start with a hyphen or digit (ascii or other) are invalid
10
- include_examples 'scan', '(?<name>abc)', 0 => [:group, :named_ab, '(?<name>', 0, 8]
11
- include_examples 'scan', "(?'name'abc)", 0 => [:group, :named_sq, "(?'name'", 0, 8]
12
- include_examples 'scan', '(?<name_1>abc)', 0 => [:group, :named_ab, '(?<name_1>', 0,10]
13
- include_examples 'scan', "(?'name_1'abc)", 0 => [:group, :named_sq, "(?'name_1'", 0,10]
14
- include_examples 'scan', '(?<name-1>abc)', 0 => [:group, :named_ab, '(?<name-1>', 0,10]
15
- include_examples 'scan', "(?'name-1'abc)", 0 => [:group, :named_sq, "(?'name-1'", 0,10]
16
- include_examples 'scan', "(?<name'1>abc)", 0 => [:group, :named_ab, "(?<name'1>", 0,10]
17
- include_examples 'scan', "(?'name>1'abc)", 0 => [:group, :named_sq, "(?'name>1'", 0,10]
18
- include_examples 'scan', '(?<üüuuüü>abc)', 0 => [:group, :named_ab, '(?<üüuuüü>', 0,10]
19
- include_examples 'scan', "(?'üüuuüü'abc)", 0 => [:group, :named_sq, "(?'üüuuüü'", 0,10]
20
- include_examples 'scan', "(?<😋1234😋>abc)", 0 => [:group, :named_ab, "(?<😋1234😋>", 0,10]
21
- include_examples 'scan', "(?'😋1234😋'abc)", 0 => [:group, :named_sq, "(?'😋1234😋'", 0,10]
22
-
23
- include_examples 'scan', '(?:abc)', 0 => [:group, :passive, '(?:', 0, 3]
24
- include_examples 'scan', '(?:)', 0 => [:group, :passive, '(?:', 0, 3]
25
- include_examples 'scan', '(?::)', 0 => [:group, :passive, '(?:', 0, 3]
26
-
27
- # Comments
28
- include_examples 'scan', '(?#abc)', 0 => [:group, :comment, '(?#abc)', 0, 7]
29
- include_examples 'scan', '(?#)', 0 => [:group, :comment, '(?#)', 0, 4]
30
-
31
- # Assertions
32
- include_examples 'scan', '(?=abc)', 0 => [:assertion, :lookahead, '(?=', 0, 3]
33
- include_examples 'scan', '(?!abc)', 0 => [:assertion, :nlookahead, '(?!', 0, 3]
34
- include_examples 'scan', '(?<=abc)', 0 => [:assertion, :lookbehind, '(?<=', 0, 4]
35
- include_examples 'scan', '(?<!abc)', 0 => [:assertion, :nlookbehind, '(?<!', 0, 4]
36
-
37
- # Options
38
- include_examples 'scan', '(?-mix:abc)', 0 => [:group, :options, '(?-mix:', 0, 7]
39
- include_examples 'scan', '(?m-ix:abc)', 0 => [:group, :options, '(?m-ix:', 0, 7]
40
- include_examples 'scan', '(?mi-x:abc)', 0 => [:group, :options, '(?mi-x:', 0, 7]
41
- include_examples 'scan', '(?mix:abc)', 0 => [:group, :options, '(?mix:', 0, 6]
42
- include_examples 'scan', '(?m:)', 0 => [:group, :options, '(?m:', 0, 4]
43
- include_examples 'scan', '(?i:)', 0 => [:group, :options, '(?i:', 0, 4]
44
- include_examples 'scan', '(?x:)', 0 => [:group, :options, '(?x:', 0, 4]
45
- include_examples 'scan', '(?mix)', 0 => [:group, :options_switch, '(?mix', 0, 5]
46
- include_examples 'scan', '(?d-mix:abc)', 0 => [:group, :options, '(?d-mix:', 0, 8]
47
- include_examples 'scan', '(?a-mix:abc)', 0 => [:group, :options, '(?a-mix:', 0, 8]
48
- include_examples 'scan', '(?u-mix:abc)', 0 => [:group, :options, '(?u-mix:', 0, 8]
49
- include_examples 'scan', '(?da-m:abc)', 0 => [:group, :options, '(?da-m:', 0, 7]
50
- include_examples 'scan', '(?du-x:abc)', 0 => [:group, :options, '(?du-x:', 0, 7]
51
- include_examples 'scan', '(?dau-i:abc)', 0 => [:group, :options, '(?dau-i:', 0, 8]
52
- include_examples 'scan', '(?dau:abc)', 0 => [:group, :options, '(?dau:', 0, 6]
53
- include_examples 'scan', '(?d:)', 0 => [:group, :options, '(?d:', 0, 4]
54
- include_examples 'scan', '(?a:)', 0 => [:group, :options, '(?a:', 0, 4]
55
- include_examples 'scan', '(?u:)', 0 => [:group, :options, '(?u:', 0, 4]
56
- include_examples 'scan', '(?dau)', 0 => [:group, :options_switch, '(?dau', 0, 5]
57
-
58
- if ruby_version_at_least('2.4.1')
59
- include_examples 'scan', '(?~abc)', 0 => [:group, :absence, '(?~', 0, 3]
60
- end
61
- end
@@ -1,10 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe('Keep scanning') do
4
- include_examples 'scan', /ab\Kcd/,
5
- 1 => [:keep, :mark, '\K', 2, 4]
6
-
7
- include_examples 'scan', /(a\Kb)|(c\\\Kd)ef/,
8
- 2 => [:keep, :mark, '\K', 2, 4],
9
- 9 => [:keep, :mark, '\K', 11, 13]
10
- end
@@ -1,39 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe('UTF8 scanning') do
4
- # ascii, single byte characters
5
- include_examples 'scan', 'a',
6
- 0 => [:literal, :literal, 'a', 0, 1]
7
-
8
- include_examples 'scan', 'ab+',
9
- 0 => [:literal, :literal, 'ab', 0, 2],
10
- 1 => [:quantifier, :one_or_more, '+', 2, 3]
11
-
12
- # 2 byte wide characters
13
- include_examples 'scan', 'äöü',
14
- 0 => [:literal, :literal, 'äöü', 0, 3]
15
-
16
- # 3 byte wide characters, Japanese
17
- include_examples 'scan', 'ab?れます+cd',
18
- 0 => [:literal, :literal, 'ab', 0, 2],
19
- 1 => [:quantifier, :zero_or_one, '?', 2, 3],
20
- 2 => [:literal, :literal, 'れます', 3, 6],
21
- 3 => [:quantifier, :one_or_more, '+', 6, 7],
22
- 4 => [:literal, :literal, 'cd', 7, 9]
23
-
24
- # 4 byte wide characters, Osmanya
25
- include_examples 'scan', '𐒀𐒁?𐒂ab+𐒃',
26
- 0 => [:literal, :literal, '𐒀𐒁', 0, 2],
27
- 1 => [:quantifier, :zero_or_one, '?', 2, 3],
28
- 2 => [:literal, :literal, '𐒂ab', 3, 6],
29
- 3 => [:quantifier, :one_or_more, '+', 6, 7],
30
- 4 => [:literal, :literal, '𐒃', 7, 8]
31
-
32
- include_examples 'scan', 'mu𝄞?si*𝄫c+',
33
- 0 => [:literal, :literal, 'mu𝄞', 0, 3],
34
- 1 => [:quantifier, :zero_or_one, '?', 3, 4],
35
- 2 => [:literal, :literal, 'si', 4, 6],
36
- 3 => [:quantifier, :zero_or_more, '*', 6, 7],
37
- 4 => [:literal, :literal, '𝄫c', 7, 9],
38
- 5 => [:quantifier, :one_or_more, '+', 9, 10]
39
- end
@@ -1,18 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe('Meta scanning') do
4
- include_examples 'scan', /abc??|def*+|ghi+/,
5
- 0 => [:literal, :literal, 'abc', 0, 3],
6
- 1 => [:quantifier, :zero_or_one_reluctant, '??', 3, 5],
7
- 2 => [:meta, :alternation, '|', 5, 6],
8
- 3 => [:literal, :literal, 'def', 6, 9],
9
- 4 => [:quantifier, :zero_or_more_possessive, '*+', 9, 11],
10
- 5 => [:meta, :alternation, '|', 11, 12]
11
-
12
- include_examples 'scan', /(a\|b)|(c|d)\|(e[|]f)/,
13
- 2 => [:escape, :alternation, '\|', 2, 4],
14
- 5 => [:meta, :alternation, '|', 6, 7],
15
- 8 => [:meta, :alternation, '|', 9, 10],
16
- 11 => [:escape, :alternation, '\|', 12, 14],
17
- 15 => [:literal, :literal, '|', 17, 18]
18
- end
@@ -1,36 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe('passing options to scan') do
4
- def expect_type_tokens(tokens, type_tokens)
5
- expect(tokens.map { |type, token, *| [type, token] }).to eq(type_tokens)
6
- end
7
-
8
- it 'raises if if scanning from a Regexp and options are passed' do
9
- expect { RS.scan(/a+/, options: ::Regexp::EXTENDED) }.to raise_error(
10
- ArgumentError,
11
- 'options cannot be supplied unless scanning a String'
12
- )
13
- end
14
-
15
- it 'sets free_spacing based on options if scanning from a String' do
16
- expect_type_tokens(
17
- RS.scan('a+#c', options: ::Regexp::MULTILINE | ::Regexp::EXTENDED),
18
- [
19
- %i[literal literal],
20
- %i[quantifier one_or_more],
21
- %i[free_space comment]
22
- ]
23
- )
24
- end
25
-
26
- it 'does not set free_spacing if scanning from a String and passing no options' do
27
- expect_type_tokens(
28
- RS.scan('a+#c'),
29
- [
30
- %i[literal literal],
31
- %i[quantifier one_or_more],
32
- %i[literal literal]
33
- ]
34
- )
35
- end
36
- end
@@ -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,25 +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
-
21
- # special case: chained quantifiers
22
- include_examples 'scan', 'a+{2}{3}', 1 => [:quantifier, :one_or_more, '+', 1, 2]
23
- include_examples 'scan', 'a+{2}{3}', 2 => [:quantifier, :interval, '{2}', 2, 5]
24
- include_examples 'scan', 'a+{2}{3}', 3 => [:quantifier, :interval, '{3}', 5, 8]
25
- end
@@ -1,55 +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
- #
9
- # NOTE: only \g supports forward-looking references using '+', e.g. \g<+1>
10
- # refers to the next group, but \k<+1> refers to a group named '+1'.
11
- # Inversely, only \k supports addition or substraction of a recursion level.
12
- # E.g. \k<x+0> refers to a group named 'x' at the current recursion level,
13
- # but \g<x+0> refers to a a group named 'x+0'.
14
- #
15
- include_examples 'scan', '(?<X>abc)\k<X>', 3 => [:backref, :name_ref_ab, '\k<X>', 9, 14]
16
- include_examples 'scan', "(?<X>abc)\\k'X'", 3 => [:backref, :name_ref_sq, "\\k'X'", 9, 14]
17
-
18
- include_examples 'scan', '(?<+1>abc)\k<+1>', 3 => [:backref, :name_ref_ab, '\k<+1>', 10, 16]
19
- include_examples 'scan', "(?<+1>abc)\\k'+1'", 3 => [:backref, :name_ref_sq, "\\k'+1'", 10, 16]
20
-
21
- include_examples 'scan', '(abc)\k<1>', 3 => [:backref, :number_ref_ab, '\k<1>', 5, 10]
22
- include_examples 'scan', "(abc)\\k'1'", 3 => [:backref, :number_ref_sq, "\\k'1'", 5, 10]
23
-
24
- include_examples 'scan', '(abc)\k<-1>', 3 => [:backref, :number_rel_ref_ab, '\k<-1>', 5, 11]
25
- include_examples 'scan', "(abc)\\k'-1'", 3 => [:backref, :number_rel_ref_sq, "\\k'-1'", 5, 11]
26
-
27
- # Sub-expression invocation, named, numbered, and relative
28
- include_examples 'scan', '(?<X>abc)\g<X>', 3 => [:backref, :name_call_ab, '\g<X>', 9, 14]
29
- include_examples 'scan', "(?<X>abc)\\g'X'", 3 => [:backref, :name_call_sq, "\\g'X'", 9, 14]
30
-
31
- include_examples 'scan', '(?<X>abc)\g<X-1>', 3 => [:backref, :name_call_ab, '\g<X-1>', 9, 16]
32
- include_examples 'scan', "(?<X>abc)\\g'X-1'", 3 => [:backref, :name_call_sq, "\\g'X-1'", 9, 16]
33
-
34
- include_examples 'scan', '(abc)\g<1>', 3 => [:backref, :number_call_ab, '\g<1>', 5, 10]
35
- include_examples 'scan', "(abc)\\g'1'", 3 => [:backref, :number_call_sq, "\\g'1'", 5, 10]
36
-
37
- include_examples 'scan', 'a(b|\g<0>)', 4 => [:backref, :number_call_ab, '\g<0>', 4, 9]
38
- include_examples 'scan', "a(b|\\g'0')", 4 => [:backref, :number_call_sq, "\\g'0'", 4, 9]
39
-
40
- include_examples 'scan', '(abc)\g<-1>', 3 => [:backref, :number_rel_call_ab, '\g<-1>', 5, 11]
41
- include_examples 'scan', "(abc)\\g'-1'", 3 => [:backref, :number_rel_call_sq, "\\g'-1'", 5, 11]
42
-
43
- include_examples 'scan', '\g<+1>(abc)', 0 => [:backref, :number_rel_call_ab, '\g<+1>', 0, 6]
44
- include_examples 'scan', "\\g'+1'(abc)", 0 => [:backref, :number_rel_call_sq, "\\g'+1'", 0, 6]
45
-
46
- # Group back-references, with recursion level
47
- include_examples 'scan', '(?<X>abc)\k<X-0>', 3 => [:backref, :name_recursion_ref_ab, '\k<X-0>', 9, 16]
48
- include_examples 'scan', "(?<X>abc)\\k'X-0'", 3 => [:backref, :name_recursion_ref_sq, "\\k'X-0'", 9, 16]
49
-
50
- include_examples 'scan', '(abc)\k<1-0>', 3 => [:backref, :number_recursion_ref_ab, '\k<1-0>', 5, 12]
51
- include_examples 'scan', "(abc)\\k'1-0'", 3 => [:backref, :number_recursion_ref_sq, "\\k'1-0'", 5, 12]
52
-
53
- include_examples 'scan', '(abc)\k<+1-0>', 3 => [:backref, :name_recursion_ref_ab, '\k<+1-0>', 5, 13]
54
- include_examples 'scan', "(abc)\\k'+1-0'", 3 => [:backref, :name_recursion_ref_sq, "\\k'+1-0'", 5, 13]
55
- end