regexp_parser 1.5.1 → 1.8.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.
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe('Literal delimiter lexing') do
4
+ include_examples 'lex', '}',
5
+ 0 => [:literal, :literal, '}', 0, 1, 0, 0, 0]
6
+
7
+ include_examples 'lex', '}}',
8
+ 0 => [:literal, :literal, '}}', 0, 2, 0, 0, 0]
9
+
10
+ include_examples 'lex', '{',
11
+ 0 => [:literal, :literal, '{', 0, 1, 0, 0, 0]
12
+
13
+ include_examples 'lex', '{{',
14
+ 0 => [:literal, :literal, '{{', 0, 2, 0, 0, 0]
15
+
16
+ include_examples 'lex', '{}',
17
+ 0 => [:literal, :literal, '{}', 0, 2, 0, 0, 0]
18
+
19
+ include_examples 'lex', '}{',
20
+ 0 => [:literal, :literal, '}{', 0, 2, 0, 0, 0]
21
+
22
+ include_examples 'lex', '}{+',
23
+ 0 => [:literal, :literal, '}', 0, 1, 0, 0, 0],
24
+ 1 => [:literal, :literal, '{', 1, 2, 0, 0, 0],
25
+ 2 => [:quantifier, :one_or_more, '+', 2, 3, 0, 0, 0]
26
+
27
+ include_examples 'lex', '{{var}}',
28
+ 0 => [:literal, :literal, '{{var}}', 0, 7, 0, 0, 0]
29
+
30
+ include_examples 'lex', 'a{b}c',
31
+ 0 => [:literal, :literal, 'a{b}c', 0, 5, 0, 0, 0]
32
+
33
+ include_examples 'lex', 'a{1,2',
34
+ 0 => [:literal, :literal, 'a{1,2', 0, 5, 0, 0, 0]
35
+
36
+ include_examples 'lex', '({.+})',
37
+ 0 => [:group, :capture, '(', 0, 1, 0, 0, 0],
38
+ 1 => [:literal, :literal, '{', 1, 2, 1, 0, 0],
39
+ 2 => [:meta, :dot, '.', 2, 3, 1, 0, 0],
40
+ 3 => [:quantifier, :one_or_more, '+', 3, 4, 1, 0, 0],
41
+ 4 => [:literal, :literal, '}', 4, 5, 1, 0, 0],
42
+ 5 => [:group, :close, ')', 5, 6, 0, 0, 0]
43
+
44
+ include_examples 'lex', ']',
45
+ 0 => [:literal, :literal, ']', 0, 1, 0, 0, 0]
46
+
47
+ include_examples 'lex', ']]',
48
+ 0 => [:literal, :literal, ']]', 0, 2, 0, 0, 0]
49
+
50
+ include_examples 'lex', ']\[',
51
+ 0 => [:literal, :literal, ']', 0, 1, 0, 0, 0],
52
+ 1 => [:escape, :set_open, '\[', 1, 3, 0, 0, 0]
53
+
54
+ include_examples 'lex', '()',
55
+ 0 => [:group, :capture, '(', 0, 1, 0, 0, 0],
56
+ 1 => [:group, :close, ')', 1, 2, 0, 0, 0]
57
+
58
+ include_examples 'lex', '{abc:.+}}}[^}]]}',
59
+ 0 => [:literal, :literal, '{abc:', 0, 5, 0, 0, 0],
60
+ 1 => [:meta, :dot, '.', 5, 6, 0, 0, 0],
61
+ 2 => [:quantifier, :one_or_more, '+', 6, 7, 0, 0, 0],
62
+ 3 => [:literal, :literal, '}}}', 7, 10, 0, 0, 0],
63
+ 4 => [:set, :open, '[', 10, 11, 0, 0, 0],
64
+ 5 => [:set, :negate, '^', 11, 12, 0, 1, 0],
65
+ 6 => [:literal, :literal, '}', 12, 13, 0, 1, 0],
66
+ 7 => [:set, :close, ']', 13, 14, 0, 0, 0],
67
+ 8 => [:literal, :literal, ']}', 14, 16, 0, 0, 0]
68
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe('passing options to parse') do
4
+ it 'raises if if parsing from a Regexp and options are passed' do
5
+ expect { RP.parse(/a+/, options: ::Regexp::EXTENDED) }.to raise_error(
6
+ ArgumentError,
7
+ 'options cannot be supplied unless parsing a String'
8
+ )
9
+ end
10
+
11
+ it 'sets options if parsing from a String' do
12
+ root = RP.parse('a+', options: ::Regexp::MULTILINE | ::Regexp::EXTENDED)
13
+
14
+ expect(root.options).to eq(m: true, x: true)
15
+ end
16
+
17
+ it 'allows options to not be supplied when parsing from a Regexp' do
18
+ root = RP.parse(/a+/ix)
19
+
20
+ expect(root.options).to eq(i: true, x: true)
21
+ end
22
+
23
+ it 'has an empty option-hash when parsing from a String and passing no options' do
24
+ root = RP.parse('a+')
25
+
26
+ expect(root.options).to be_empty
27
+ end
28
+ end
@@ -65,7 +65,7 @@ RSpec.describe('Property parsing') do
65
65
  end
66
66
 
67
67
  specify('parse property shortcut') do
68
- expect(RP.parse('\p{mark}')[0].shortcut).to eq 'm'
68
+ expect(RP.parse('\p{lowercase_letter}')[0].shortcut).to eq 'll'
69
69
  expect(RP.parse('\p{sc}')[0].shortcut).to eq 'sc'
70
70
  expect(RP.parse('\p{in_bengali}')[0].shortcut).to be_nil
71
71
  end
@@ -35,6 +35,7 @@ RSpec.describe('Quantifier parsing') do
35
35
  include_examples 'quantifier', /a{4}b/, '{4}', :greedy, :interval, 4, 4
36
36
  include_examples 'quantifier', /a{4}?b/, '{4}?', :reluctant, :interval, 4, 4
37
37
  include_examples 'quantifier', /a{4}+b/, '{4}+', :possessive, :interval, 4, 4
38
+ include_examples 'quantifier', /a{004}+b/, '{004}+', :possessive, :interval, 4, 4
38
39
 
39
40
  specify('mode-checking methods') do
40
41
  exp = RP.parse(/a??/).first
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe('Literal delimiter scanning') do
4
+ include_examples 'scan', '}',
5
+ 0 => [:literal, :literal, '}', 0, 1]
6
+
7
+ include_examples 'scan', '}}',
8
+ 0 => [:literal, :literal, '}}', 0, 2]
9
+
10
+ include_examples 'scan', '{',
11
+ 0 => [:literal, :literal, '{', 0, 1]
12
+
13
+ include_examples 'scan', '{{',
14
+ 0 => [:literal, :literal, '{{', 0, 2]
15
+
16
+ include_examples 'scan', '{}',
17
+ 0 => [:literal, :literal, '{}', 0, 2]
18
+
19
+ include_examples 'scan', '}{',
20
+ 0 => [:literal, :literal, '}{', 0, 2]
21
+
22
+ include_examples 'scan', '}{+',
23
+ 0 => [:literal, :literal, '}{', 0, 2]
24
+
25
+ include_examples 'scan', '{{var}}',
26
+ 0 => [:literal, :literal, '{{var}}', 0, 7]
27
+
28
+ include_examples 'scan', 'a{1,2',
29
+ 0 => [:literal, :literal, 'a{1,2', 0, 5]
30
+
31
+ include_examples 'scan', '({.+})',
32
+ 0 => [:group, :capture, '(', 0, 1],
33
+ 1 => [:literal, :literal, '{', 1, 2],
34
+ 2 => [:meta, :dot, '.', 2, 3],
35
+ 3 => [:quantifier, :one_or_more, '+', 3, 4],
36
+ 4 => [:literal, :literal, '}', 4, 5],
37
+ 5 => [:group, :close, ')', 5, 6]
38
+
39
+ include_examples 'scan', ']',
40
+ 0 => [:literal, :literal, ']', 0, 1]
41
+
42
+ include_examples 'scan', ']]',
43
+ 0 => [:literal, :literal, ']]', 0, 2]
44
+
45
+ include_examples 'scan', ']\[',
46
+ 0 => [:literal, :literal, ']', 0, 1],
47
+ 1 => [:escape, :set_open, '\[', 1, 3]
48
+
49
+ include_examples 'scan', '()',
50
+ 0 => [:group, :capture, '(', 0, 1],
51
+ 1 => [:group, :close, ')', 1, 2]
52
+ end
@@ -10,7 +10,6 @@ RSpec.describe(Regexp::Scanner) do
10
10
  include_examples 'scan error', RS::PrematureEndError, 'unbalanced set', '[a'
11
11
  include_examples 'scan error', RS::PrematureEndError, 'unbalanced set', '[[:alpha:]'
12
12
  include_examples 'scan error', RS::PrematureEndError, 'unbalanced group', '(abc'
13
- include_examples 'scan error', RS::PrematureEndError, 'unbalanced interval', 'a{1,2'
14
13
  include_examples 'scan error', RS::PrematureEndError, 'eof in property', '\p{asci'
15
14
  include_examples 'scan error', RS::PrematureEndError, 'incomplete property', '\p{ascii abc'
16
15
  include_examples 'scan error', RS::PrematureEndError, 'eof options', '(?mix'
@@ -13,6 +13,10 @@ RSpec.describe('Escape scanning') do
13
13
 
14
14
  include_examples 'scan', 'c\qt', 1 => [:escape, :literal, '\q', 1, 3]
15
15
 
16
+ # these incomplete ref/call sequences are treated as literal escapes by Ruby
17
+ include_examples 'scan', 'c\gt', 1 => [:escape, :literal, '\g', 1, 3]
18
+ include_examples 'scan', 'c\kt', 1 => [:escape, :literal, '\k', 1, 3]
19
+
16
20
  include_examples 'scan', 'a\012c', 1 => [:escape, :octal, '\012', 1, 5]
17
21
  include_examples 'scan', 'a\0124', 1 => [:escape, :octal, '\012', 1, 5]
18
22
  include_examples 'scan', '\712+7', 0 => [:escape, :octal, '\712', 0, 4]
@@ -39,6 +39,17 @@ RSpec.describe('FreeSpace scanning') do
39
39
  11 => [:free_space, :comment, "# B ? comment\n", 37, 51],
40
40
  17 => [:free_space, :comment, "# C {2,3} comment\n", 66, 84],
41
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]
42
53
  end
43
54
 
44
55
  describe('scan free space inlined') do
@@ -130,4 +141,25 @@ RSpec.describe('FreeSpace scanning') do
130
141
  26 => [:literal, :literal, 'i j', 35, 38],
131
142
  27 => [:group, :close, ')', 38, 39]
132
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
133
165
  end
@@ -0,0 +1,36 @@
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
@@ -25,7 +25,9 @@ RSpec.describe(Regexp::Syntax) do
25
25
  include_examples 'syntax alias', 'ruby/2.5.0', Regexp::Syntax::V2_4_1
26
26
  include_examples 'syntax alias', 'ruby/2.5', Regexp::Syntax::V2_5_0
27
27
  include_examples 'syntax alias', 'ruby/2.6.0', Regexp::Syntax::V2_5_0
28
- include_examples 'syntax alias', 'ruby/2.6', 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
29
31
 
30
32
  specify('future alias warning') do
31
33
  expect { Regexp::Syntax.new('ruby/5.0') }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: regexp_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.1
4
+ version: 1.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ammar Ali
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-23 00:00:00.000000000 Z
11
+ date: 2020-09-28 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A library for tokenizing, lexing, and parsing Ruby regular expressions.
14
14
  email:
@@ -87,6 +87,8 @@ files:
87
87
  - lib/regexp_parser/syntax/versions/2.4.1.rb
88
88
  - lib/regexp_parser/syntax/versions/2.5.0.rb
89
89
  - lib/regexp_parser/syntax/versions/2.6.0.rb
90
+ - lib/regexp_parser/syntax/versions/2.6.2.rb
91
+ - lib/regexp_parser/syntax/versions/2.6.3.rb
90
92
  - lib/regexp_parser/token.rb
91
93
  - lib/regexp_parser/version.rb
92
94
  - regexp_parser.gemspec
@@ -107,6 +109,7 @@ files:
107
109
  - spec/expression/to_s_spec.rb
108
110
  - spec/lexer/all_spec.rb
109
111
  - spec/lexer/conditionals_spec.rb
112
+ - spec/lexer/delimiters_spec.rb
110
113
  - spec/lexer/escapes_spec.rb
111
114
  - spec/lexer/keep_spec.rb
112
115
  - spec/lexer/literals_spec.rb
@@ -121,6 +124,7 @@ files:
121
124
  - spec/parser/free_space_spec.rb
122
125
  - spec/parser/groups_spec.rb
123
126
  - spec/parser/keep_spec.rb
127
+ - spec/parser/options_spec.rb
124
128
  - spec/parser/posix_classes_spec.rb
125
129
  - spec/parser/properties_spec.rb
126
130
  - spec/parser/quantifiers_spec.rb
@@ -132,6 +136,7 @@ files:
132
136
  - spec/scanner/all_spec.rb
133
137
  - spec/scanner/anchors_spec.rb
134
138
  - spec/scanner/conditionals_spec.rb
139
+ - spec/scanner/delimiters_spec.rb
135
140
  - spec/scanner/errors_spec.rb
136
141
  - spec/scanner/escapes_spec.rb
137
142
  - spec/scanner/free_space_spec.rb
@@ -139,6 +144,7 @@ files:
139
144
  - spec/scanner/keep_spec.rb
140
145
  - spec/scanner/literals_spec.rb
141
146
  - spec/scanner/meta_spec.rb
147
+ - spec/scanner/options_spec.rb
142
148
  - spec/scanner/properties_spec.rb
143
149
  - spec/scanner/quantifiers_spec.rb
144
150
  - spec/scanner/refcalls_spec.rb
@@ -162,7 +168,7 @@ licenses:
162
168
  - MIT
163
169
  metadata:
164
170
  issue_tracker: https://github.com/ammar/regexp_parser/issues
165
- post_install_message:
171
+ post_install_message:
166
172
  rdoc_options:
167
173
  - "--inline-source"
168
174
  - "--charset=UTF-8"
@@ -172,15 +178,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
172
178
  requirements:
173
179
  - - ">="
174
180
  - !ruby/object:Gem::Version
175
- version: 1.9.1
181
+ version: 2.0.0
176
182
  required_rubygems_version: !ruby/object:Gem::Requirement
177
183
  requirements:
178
184
  - - ">="
179
185
  - !ruby/object:Gem::Version
180
186
  version: '0'
181
187
  requirements: []
182
- rubygems_version: 3.0.3
183
- signing_key:
188
+ rubygems_version: 3.1.2
189
+ signing_key:
184
190
  specification_version: 4
185
191
  summary: Scanner, lexer, parser for ruby's regular expressions
186
192
  test_files:
@@ -191,6 +197,7 @@ test_files:
191
197
  - spec/lexer/all_spec.rb
192
198
  - spec/lexer/conditionals_spec.rb
193
199
  - spec/lexer/nesting_spec.rb
200
+ - spec/lexer/delimiters_spec.rb
194
201
  - spec/lexer/refcalls_spec.rb
195
202
  - spec/lexer/literals_spec.rb
196
203
  - spec/parser/escapes_spec.rb
@@ -198,6 +205,7 @@ test_files:
198
205
  - spec/parser/sets_spec.rb
199
206
  - spec/parser/free_space_spec.rb
200
207
  - spec/parser/keep_spec.rb
208
+ - spec/parser/options_spec.rb
201
209
  - spec/parser/all_spec.rb
202
210
  - spec/parser/conditionals_spec.rb
203
211
  - spec/parser/types_spec.rb
@@ -241,12 +249,14 @@ test_files:
241
249
  - spec/scanner/sets_spec.rb
242
250
  - spec/scanner/free_space_spec.rb
243
251
  - spec/scanner/keep_spec.rb
252
+ - spec/scanner/options_spec.rb
244
253
  - spec/scanner/all_spec.rb
245
254
  - spec/scanner/conditionals_spec.rb
246
255
  - spec/scanner/types_spec.rb
247
256
  - spec/scanner/anchors_spec.rb
248
257
  - spec/scanner/meta_spec.rb
249
258
  - spec/scanner/errors_spec.rb
259
+ - spec/scanner/delimiters_spec.rb
250
260
  - spec/scanner/refcalls_spec.rb
251
261
  - spec/scanner/groups_spec.rb
252
262
  - spec/scanner/literals_spec.rb