regexp_parser 0.1.5 → 0.1.6
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.
- checksums.yaml +4 -4
- data/ChangeLog +37 -0
- data/README.md +443 -0
- data/Rakefile +28 -46
- data/VERSION.yml +1 -1
- data/lib/regexp_parser/parser.rb +3 -1
- data/lib/regexp_parser/scanner.rb +29 -34
- data/lib/regexp_parser/scanner/scanner.rl +2 -2
- data/lib/regexp_parser/syntax.rb +13 -3
- data/lib/regexp_parser/syntax/ruby/2.0.0.rb +2 -2
- data/lib/regexp_parser/syntax/ruby/2.0.rb +8 -0
- data/lib/regexp_parser/syntax/ruby/2.1.0.rb +2 -2
- data/lib/regexp_parser/syntax/ruby/2.1.2.rb +13 -0
- data/lib/regexp_parser/syntax/ruby/2.1.3.rb +13 -0
- data/lib/regexp_parser/syntax/ruby/2.1.rb +8 -0
- data/test/parser/test_alternation.rb +11 -0
- data/test/parser/test_sets.rb +7 -0
- data/test/scanner/test_sets.rb +1 -0
- data/test/syntax/ruby/test_2.x.rb +46 -0
- data/test/syntax/ruby/test_all.rb +1 -1
- metadata +15 -14
- data/README.rdoc +0 -307
- data/test/scanner/test_conditionals.rb +0 -31
- data/test/scanner/test_quoting.rb +0 -29
data/Rakefile
CHANGED
@@ -1,32 +1,48 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
1
3
|
require 'rake'
|
2
4
|
require 'rake/testtask'
|
5
|
+
|
6
|
+
require 'bundler'
|
3
7
|
require 'rubygems/package_task'
|
4
|
-
require 'yaml'
|
5
8
|
|
6
|
-
task :default => [:test]
|
7
9
|
|
8
10
|
RAGEL_SOURCE_DIR = File.expand_path '../lib/regexp_parser/scanner', __FILE__
|
9
11
|
RAGEL_OUTPUT_DIR = File.expand_path '../lib/regexp_parser', __FILE__
|
12
|
+
RAGEL_SOURCE_FILES = %w{scanner} # scanner.rl includes property.rl
|
13
|
+
|
10
14
|
|
11
|
-
|
15
|
+
Bundler::GemHelper.install_tasks
|
16
|
+
|
17
|
+
|
18
|
+
task :default => [:test]
|
19
|
+
|
20
|
+
Rake::TestTask.new('test') do |t|
|
21
|
+
t.description = "Run all unit tests under the test directory"
|
12
22
|
|
13
|
-
desc "Find and run all unit tests under test/ directory"
|
14
|
-
Rake::TestTask.new("test") do |t|
|
15
23
|
t.libs << "test"
|
16
|
-
t.test_files = FileList['test
|
24
|
+
t.test_files = FileList['test/test_all.rb']
|
17
25
|
end
|
18
26
|
|
19
|
-
task :test
|
20
|
-
|
21
27
|
namespace :test do
|
22
28
|
%w{scanner lexer parser expression syntax}.each do |component|
|
23
29
|
Rake::TestTask.new(component) do |t|
|
30
|
+
t.description = "Run all #{component} unit tests under the test/#{component} directory"
|
31
|
+
|
24
32
|
t.libs << "test"
|
25
33
|
t.test_files = ["test/#{component}/test_all.rb"]
|
26
34
|
end
|
27
35
|
end
|
36
|
+
|
37
|
+
Rake::TestTask.new('full' => 'ragel:rb') do |t|
|
38
|
+
t.description = "Regenerate the scanner and run all unit tests under the test directory"
|
39
|
+
|
40
|
+
t.libs << "test"
|
41
|
+
t.test_files = FileList['test/test_all.rb']
|
42
|
+
end
|
28
43
|
end
|
29
44
|
|
45
|
+
|
30
46
|
namespace :ragel do
|
31
47
|
desc "Process the ragel source files and output ruby code"
|
32
48
|
task :rb do |t|
|
@@ -44,43 +60,9 @@ namespace :ragel do
|
|
44
60
|
end
|
45
61
|
end
|
46
62
|
|
47
|
-
spec = Gem::Specification.new do |gem|
|
48
|
-
gem.name = 'regexp_parser'
|
49
|
-
gem.version = YAML.load(File.read('VERSION.yml')).values.compact.join('.')
|
50
|
-
gem.date = '2014-01-14'
|
51
|
-
|
52
|
-
gem.license = 'MIT'
|
53
|
-
gem.summary = %q{Scanner, lexer, parser for ruby's regular expressions}
|
54
|
-
gem.description = %q{A library for tokenizing, lexing, and parsing Ruby regular expressions.}
|
55
|
-
gem.homepage = %q{http://github.com/ammar/regexp_parser}
|
56
|
-
|
57
|
-
gem.authors = ["Ammar Ali"]
|
58
|
-
gem.email = 'ammarabuali@gmail.com'
|
59
|
-
|
60
|
-
gem.rdoc_options = ["--inline-source", "--charset=UTF-8"]
|
61
|
-
gem.extra_rdoc_files = ["ChangeLog", "LICENSE", "README.rdoc"]
|
62
|
-
|
63
|
-
gem.require_paths = ["lib"]
|
64
|
-
|
65
|
-
gem.files = Dir.glob("{lib,test}/**/*.rb") + Dir.glob("lib/**/*.rl") +
|
66
|
-
%w(VERSION.yml Rakefile LICENSE README.rdoc ChangeLog)
|
67
63
|
|
68
|
-
|
64
|
+
# Add ragel task as a prerequisite for building the gem to ensure that the
|
65
|
+
# latest scanner code is generated and included in the build.
|
66
|
+
desc "Runs ragel:rb before building the gem"
|
67
|
+
task :build => ['ragel:rb']
|
69
68
|
|
70
|
-
gem.required_rubygems_version = Gem::Requirement.new(">= 0") if
|
71
|
-
gem.respond_to? :required_rubygems_version=
|
72
|
-
end
|
73
|
-
|
74
|
-
Gem::PackageTask.new(spec) do |pkg|
|
75
|
-
pkg.need_zip = true
|
76
|
-
pkg.need_tar = true
|
77
|
-
end
|
78
|
-
|
79
|
-
namespace :gem do
|
80
|
-
desc "Release the gem to rubygems.org"
|
81
|
-
task :release do |t|
|
82
|
-
Rake::Task['ragel:rb'].execute
|
83
|
-
Rake::Task['repackage'].execute
|
84
|
-
#sh "gem push"
|
85
|
-
end
|
86
|
-
end
|
data/VERSION.yml
CHANGED
data/lib/regexp_parser/parser.rb
CHANGED
@@ -406,8 +406,10 @@ module Regexp::Parser
|
|
406
406
|
end
|
407
407
|
|
408
408
|
def self.close_group
|
409
|
-
|
409
|
+
@nesting.pop
|
410
|
+
|
410
411
|
@node = @nesting.last
|
412
|
+
@node = @node.last if @node.last and @node.last.is_a?(Alternation)
|
411
413
|
end
|
412
414
|
|
413
415
|
def self.open_set(token)
|
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
|
7
7
|
# THIS IS A GENERATED FILE, DO NOT EDIT DIRECTLY
|
8
|
-
# This file was generated from scanner.rl
|
8
|
+
# This file was generated from lib/regexp_parser/scanner/scanner.rl
|
9
9
|
|
10
10
|
module Regexp::Scanner
|
11
11
|
|
@@ -1226,7 +1226,7 @@ self._re_scanner_trans_targs = [
|
|
1226
1226
|
154, 155, 156, 145, 145, 145, 145, 45,
|
1227
1227
|
47, 50, 145, 145, 51, 145, 145, 52,
|
1228
1228
|
55, 103, 106, 107, 109, 161, 162, 157,
|
1229
|
-
162,
|
1229
|
+
162, 157, 157, 157, 163, 157, 164, 157,
|
1230
1230
|
112, 166, 157, 157, 167, 167, 168, 168,
|
1231
1231
|
167, 115, 116, 167, 167, 119, 129, 167,
|
1232
1232
|
169, 167, 167, 167, 167, 117, 167, 167,
|
@@ -2292,6 +2292,30 @@ te = p+1
|
|
2292
2292
|
next
|
2293
2293
|
end
|
2294
2294
|
|
2295
|
+
end
|
2296
|
+
end
|
2297
|
+
when 69 then
|
2298
|
+
# line 242 "/Users/ammar/src/ruby/projects/regexp_parser/lib/regexp_parser/scanner/scanner.rl"
|
2299
|
+
begin
|
2300
|
+
te = p+1
|
2301
|
+
begin
|
2302
|
+
case text = text(data, ts, te, 1).first
|
2303
|
+
when '\d'; emit(set_type, :type_digit, text, ts-1, te)
|
2304
|
+
when '\D'; emit(set_type, :type_nondigit, text, ts-1, te)
|
2305
|
+
when '\h'; emit(set_type, :type_hex, text, ts-1, te)
|
2306
|
+
when '\H'; emit(set_type, :type_nonhex, text, ts-1, te)
|
2307
|
+
when '\s'; emit(set_type, :type_space, text, ts-1, te)
|
2308
|
+
when '\S'; emit(set_type, :type_nonspace, text, ts-1, te)
|
2309
|
+
when '\w'; emit(set_type, :type_word, text, ts-1, te)
|
2310
|
+
when '\W'; emit(set_type, :type_nonword, text, ts-1, te)
|
2311
|
+
end
|
2312
|
+
begin
|
2313
|
+
top -= 1
|
2314
|
+
cs = stack[top]
|
2315
|
+
_goto_level = _again
|
2316
|
+
next
|
2317
|
+
end
|
2318
|
+
|
2295
2319
|
end
|
2296
2320
|
end
|
2297
2321
|
when 75 then
|
@@ -2419,27 +2443,6 @@ p = p - 1; begin
|
|
2419
2443
|
next
|
2420
2444
|
end
|
2421
2445
|
end
|
2422
|
-
when 15 then
|
2423
|
-
begin begin p = ((te))-1; end
|
2424
|
-
|
2425
|
-
case text = text(data, ts, te, 1).first
|
2426
|
-
when '\d'; emit(set_type, :type_digit, text, ts-1, te)
|
2427
|
-
when '\D'; emit(set_type, :type_nondigit, text, ts-1, te)
|
2428
|
-
when '\h'; emit(set_type, :type_hex, text, ts-1, te)
|
2429
|
-
when '\H'; emit(set_type, :type_nonhex, text, ts-1, te)
|
2430
|
-
when '\s'; emit(set_type, :type_space, text, ts-1, te)
|
2431
|
-
when '\S'; emit(set_type, :type_nonspace, text, ts-1, te)
|
2432
|
-
when '\w'; emit(set_type, :type_word, text, ts-1, te)
|
2433
|
-
when '\W'; emit(set_type, :type_nonword, text, ts-1, te)
|
2434
|
-
end
|
2435
|
-
begin
|
2436
|
-
top -= 1
|
2437
|
-
cs = stack[top]
|
2438
|
-
_goto_level = _again
|
2439
|
-
next
|
2440
|
-
end
|
2441
|
-
|
2442
|
-
end
|
2443
2446
|
when 18 then
|
2444
2447
|
begin begin p = ((te))-1; end
|
2445
2448
|
|
@@ -3428,14 +3431,6 @@ te = p+1
|
|
3428
3431
|
# line 136 "/Users/ammar/src/ruby/projects/regexp_parser/lib/regexp_parser/scanner/scanner.rl"
|
3429
3432
|
begin
|
3430
3433
|
group_depth += 1; in_group = true end
|
3431
|
-
when 69 then
|
3432
|
-
# line 1 "NONE"
|
3433
|
-
begin
|
3434
|
-
te = p+1
|
3435
|
-
end
|
3436
|
-
# line 242 "/Users/ammar/src/ruby/projects/regexp_parser/lib/regexp_parser/scanner/scanner.rl"
|
3437
|
-
begin
|
3438
|
-
act = 15; end
|
3439
3434
|
when 68 then
|
3440
3435
|
# line 1 "NONE"
|
3441
3436
|
begin
|
@@ -3476,7 +3471,7 @@ te = p+1
|
|
3476
3471
|
# line 672 "/Users/ammar/src/ruby/projects/regexp_parser/lib/regexp_parser/scanner/scanner.rl"
|
3477
3472
|
begin
|
3478
3473
|
act = 53; end
|
3479
|
-
# line
|
3474
|
+
# line 3475 "/Users/ammar/src/ruby/projects/regexp_parser/lib/regexp_parser/scanner.rb"
|
3480
3475
|
end
|
3481
3476
|
end
|
3482
3477
|
end
|
@@ -3494,7 +3489,7 @@ ts = nil; end
|
|
3494
3489
|
begin
|
3495
3490
|
act = 0
|
3496
3491
|
end
|
3497
|
-
# line
|
3492
|
+
# line 3493 "/Users/ammar/src/ruby/projects/regexp_parser/lib/regexp_parser/scanner.rb"
|
3498
3493
|
end
|
3499
3494
|
|
3500
3495
|
if cs == 0
|
@@ -3528,7 +3523,7 @@ act = 0
|
|
3528
3523
|
text = ts ? copy(data, ts-1..-1) : data.pack('c*')
|
3529
3524
|
raise PrematureEndError.new( text )
|
3530
3525
|
end
|
3531
|
-
# line
|
3526
|
+
# line 3527 "/Users/ammar/src/ruby/projects/regexp_parser/lib/regexp_parser/scanner.rb"
|
3532
3527
|
end
|
3533
3528
|
end
|
3534
3529
|
|
@@ -239,7 +239,7 @@
|
|
239
239
|
fret;
|
240
240
|
};
|
241
241
|
|
242
|
-
char_type {
|
242
|
+
char_type > (escaped_set_alpha, 4) {
|
243
243
|
case text = text(data, ts, te, 1).first
|
244
244
|
when '\d'; emit(set_type, :type_digit, text, ts-1, te)
|
245
245
|
when '\D'; emit(set_type, :type_nondigit, text, ts-1, te)
|
@@ -677,7 +677,7 @@
|
|
677
677
|
}%%
|
678
678
|
|
679
679
|
# THIS IS A GENERATED FILE, DO NOT EDIT DIRECTLY
|
680
|
-
# This file was generated from scanner.rl
|
680
|
+
# This file was generated from lib/regexp_parser/scanner/scanner.rl
|
681
681
|
|
682
682
|
module Regexp::Scanner
|
683
683
|
%% write data;
|
data/lib/regexp_parser/syntax.rb
CHANGED
@@ -37,12 +37,15 @@ module Regexp::Syntax
|
|
37
37
|
self.load(name)
|
38
38
|
|
39
39
|
case name
|
40
|
+
# Ruby 1.8.x (NOTE: 1.8.6 is no longer a supported runtime,
|
41
|
+
# but its regex features are still recognized.)
|
40
42
|
when 'ruby/1.8.6'; syntax = Regexp::Syntax::Ruby::V186.new
|
41
43
|
when 'ruby/1.8.7'; syntax = Regexp::Syntax::Ruby::V187.new
|
42
44
|
|
43
45
|
# alias for the latest 1.8 implementation
|
44
46
|
when 'ruby/1.8'; syntax = Regexp::Syntax::Ruby::V18.new
|
45
47
|
|
48
|
+
# Ruby 1.9.x
|
46
49
|
when 'ruby/1.9.1'; syntax = Regexp::Syntax::Ruby::V191.new
|
47
50
|
when 'ruby/1.9.2'; syntax = Regexp::Syntax::Ruby::V192.new
|
48
51
|
when 'ruby/1.9.3'; syntax = Regexp::Syntax::Ruby::V193.new
|
@@ -50,11 +53,18 @@ module Regexp::Syntax
|
|
50
53
|
# alias for the latest 1.9 implementation
|
51
54
|
when 'ruby/1.9'; syntax = Regexp::Syntax::Ruby::V19.new
|
52
55
|
|
53
|
-
|
54
|
-
when 'ruby/2.
|
56
|
+
# Ruby 2.0.x
|
57
|
+
when 'ruby/2.0.0'; syntax = Regexp::Syntax::Ruby::V200.new
|
55
58
|
|
56
|
-
# aliases for the latest 2.
|
59
|
+
# aliases for the latest 2.0 implementations
|
57
60
|
when 'ruby/2.0'; syntax = Regexp::Syntax::Ruby::V20.new
|
61
|
+
|
62
|
+
# Ruby 2.1.x
|
63
|
+
when 'ruby/2.1.0'; syntax = Regexp::Syntax::Ruby::V210.new
|
64
|
+
when 'ruby/2.1.2'; syntax = Regexp::Syntax::Ruby::V212.new
|
65
|
+
when 'ruby/2.1.3'; syntax = Regexp::Syntax::Ruby::V213.new
|
66
|
+
|
67
|
+
# aliases for the latest 2.1 implementations
|
58
68
|
when 'ruby/2.1'; syntax = Regexp::Syntax::Ruby::V21.new
|
59
69
|
|
60
70
|
else
|
@@ -1,10 +1,10 @@
|
|
1
|
-
require File.expand_path('../1.9
|
1
|
+
require File.expand_path('../1.9', __FILE__)
|
2
2
|
|
3
3
|
module Regexp::Syntax
|
4
4
|
module Ruby
|
5
5
|
|
6
6
|
# use the last 1.9 release as the base
|
7
|
-
class
|
7
|
+
class V200 < Regexp::Syntax::Ruby::V19
|
8
8
|
def initialize
|
9
9
|
super
|
10
10
|
|
@@ -78,4 +78,15 @@ class ParserAlternation < Test::Unit::TestCase
|
|
78
78
|
assert_equal( true, subalts[1].is_a?(Sequence) )
|
79
79
|
end
|
80
80
|
|
81
|
+
def test_parse_alternation_continues_after_nesting
|
82
|
+
root = RP.parse(/a|(b)c/)
|
83
|
+
|
84
|
+
seq = root.expressions[0][1].expressions
|
85
|
+
|
86
|
+
assert_equal( 2, seq.length )
|
87
|
+
|
88
|
+
assert_equal( true, seq[0].is_a?(Group::Capture) )
|
89
|
+
assert_equal( true, seq[1].is_a?(Literal) )
|
90
|
+
end
|
91
|
+
|
81
92
|
end
|
data/test/parser/test_sets.rb
CHANGED
@@ -36,6 +36,13 @@ class TestParserSets < Test::Unit::TestCase
|
|
36
36
|
assert_equal( false, exp.include?(']') )
|
37
37
|
end
|
38
38
|
|
39
|
+
def test_parse_chat_type_set_members
|
40
|
+
exp = RP.parse('[\da-z]', :any)[0]
|
41
|
+
|
42
|
+
assert_equal( true, exp.include?('\d') )
|
43
|
+
assert_equal( true, exp.include?('a-z') )
|
44
|
+
end
|
45
|
+
|
39
46
|
def test_parse_set_collating_sequence
|
40
47
|
exp = RP.parse('[a[.span-ll.]h]', :any)[0]
|
41
48
|
|
data/test/scanner/test_sets.rb
CHANGED
@@ -28,6 +28,7 @@ class ScannerSets < Test::Unit::TestCase
|
|
28
28
|
'[a\-c]' => [2, :set, :escape, '\-', 2, 4],
|
29
29
|
|
30
30
|
'[\d]' => [1, :set, :type_digit, '\d', 1, 3],
|
31
|
+
'[\da-z]' => [1, :set, :type_digit, '\d', 1, 3],
|
31
32
|
'[\D]' => [1, :set, :type_nondigit, '\D', 1, 3],
|
32
33
|
|
33
34
|
'[\h]' => [1, :set, :type_hex, '\h', 1, 3],
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require File.expand_path("../../../helpers", __FILE__)
|
2
|
+
|
3
|
+
class TestSyntaxRuby_V2x < Test::Unit::TestCase
|
4
|
+
|
5
|
+
# Since the only Regular expression change that was introduced in ruby 2.x
|
6
|
+
# (the conditional expressions) is not supportted yet, these tests only
|
7
|
+
# check that the syntax files have the correct inheritance (based off the
|
8
|
+
# last release) and load without error.
|
9
|
+
|
10
|
+
def test_syntax_file_2_0_0
|
11
|
+
syntax = Regexp::Syntax.new 'ruby/2.0.0'
|
12
|
+
|
13
|
+
assert_equal( true, syntax.kind_of?(Regexp::Syntax::Ruby::V19) )
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_syntax_file_2_0_alias
|
17
|
+
syntax = Regexp::Syntax.new 'ruby/2.0'
|
18
|
+
|
19
|
+
assert_equal( true, syntax.kind_of?(Regexp::Syntax::Ruby::V200) )
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_syntax_file_2_1_0
|
23
|
+
syntax = Regexp::Syntax.new 'ruby/2.1.0'
|
24
|
+
|
25
|
+
assert_equal( true, syntax.kind_of?(Regexp::Syntax::Ruby::V20) )
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_syntax_file_2_1_2
|
29
|
+
syntax = Regexp::Syntax.new 'ruby/2.1.2'
|
30
|
+
|
31
|
+
assert_equal( true, syntax.kind_of?(Regexp::Syntax::Ruby::V210) )
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_syntax_file_2_1_3
|
35
|
+
syntax = Regexp::Syntax.new 'ruby/2.1.3'
|
36
|
+
|
37
|
+
assert_equal( true, syntax.kind_of?(Regexp::Syntax::Ruby::V212) )
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_syntax_file_2_1_alias
|
41
|
+
syntax = Regexp::Syntax.new 'ruby/2.1'
|
42
|
+
|
43
|
+
assert_equal( true, syntax.kind_of?(Regexp::Syntax::Ruby::V213) )
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|