srl_ruby 0.3.5 → 0.4.0
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/.rubocop.yml +9 -3
- data/CHANGELOG.md +20 -0
- data/README.md +326 -52
- data/bin/srl2ruby +95 -0
- data/bin/srl2ruby_cli_parser.rb +89 -0
- data/lib/regex/abstract_method.rb +1 -1
- data/lib/regex/alternation.rb +1 -1
- data/lib/regex/anchor.rb +3 -3
- data/lib/regex/atomic_expression.rb +2 -2
- data/lib/regex/capturing_group.rb +3 -3
- data/lib/regex/char_class.rb +5 -5
- data/lib/regex/char_range.rb +5 -5
- data/lib/regex/char_shorthand.rb +2 -2
- data/lib/regex/character.rb +6 -6
- data/lib/regex/compound_expression.rb +2 -2
- data/lib/regex/concatenation.rb +3 -3
- data/lib/regex/expression.rb +4 -4
- data/lib/regex/lookaround.rb +1 -1
- data/lib/regex/match_option.rb +2 -2
- data/lib/regex/monadic_expression.rb +3 -3
- data/lib/regex/multiplicity.rb +1 -1
- data/lib/regex/non_capturing_group.rb +1 -1
- data/lib/regex/polyadic_expression.rb +3 -3
- data/lib/regex/repetition.rb +2 -2
- data/lib/regex/wildcard.rb +3 -3
- data/lib/srl_ruby/ast_builder.rb +22 -22
- data/lib/srl_ruby/srl_token.rb +1 -1
- data/lib/srl_ruby/tokenizer.rb +7 -7
- data/lib/srl_ruby/version.rb +1 -1
- data/spec/acceptance/srl_test_suite_spec.rb +1 -1
- data/spec/acceptance/support/rule_file_ast_builder.rb +8 -8
- data/spec/acceptance/support/rule_file_token.rb +1 -1
- data/spec/acceptance/support/rule_file_tokenizer.rb +8 -8
- data/spec/regex/character_spec.rb +30 -30
- data/spec/regex/multiplicity_spec.rb +24 -24
- data/srl_ruby.gemspec +8 -5
- data/templates/base.erb +2 -0
- data/templates/srl_and_ruby.erb +9 -0
- data/templates/srl_block_and_ruby.erb +10 -0
- metadata +8 -4
- data/bin/srl_ruby +0 -51
@@ -44,7 +44,7 @@ module Acceptance
|
|
44
44
|
@state = :default
|
45
45
|
end
|
46
46
|
|
47
|
-
def tokens
|
47
|
+
def tokens
|
48
48
|
tok_sequence = []
|
49
49
|
until @scanner.eos?
|
50
50
|
token = _next_token
|
@@ -56,7 +56,7 @@ module Acceptance
|
|
56
56
|
|
57
57
|
private
|
58
58
|
|
59
|
-
def _next_token
|
59
|
+
def _next_token
|
60
60
|
skip_noise
|
61
61
|
curr_ch = scanner.peek(1)
|
62
62
|
return nil if curr_ch.nil? || curr_ch.empty?
|
@@ -70,7 +70,7 @@ module Acceptance
|
|
70
70
|
return token
|
71
71
|
end
|
72
72
|
|
73
|
-
def default_mode
|
73
|
+
def default_mode
|
74
74
|
curr_ch = scanner.peek(1)
|
75
75
|
token = nil
|
76
76
|
|
@@ -100,7 +100,7 @@ module Acceptance
|
|
100
100
|
return token
|
101
101
|
end
|
102
102
|
|
103
|
-
def expecting_srl
|
103
|
+
def expecting_srl
|
104
104
|
scanner.skip(/^:/)
|
105
105
|
lexeme = scanner.scan(/[^\r\n]*/)
|
106
106
|
@state = :default
|
@@ -120,7 +120,7 @@ module Acceptance
|
|
120
120
|
return token
|
121
121
|
end
|
122
122
|
|
123
|
-
def skip_noise
|
123
|
+
def skip_noise
|
124
124
|
loop do
|
125
125
|
noise_found = false
|
126
126
|
noise_found = true if skip_whitespaces
|
@@ -129,7 +129,7 @@ module Acceptance
|
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
132
|
-
def skip_whitespaces
|
132
|
+
def skip_whitespaces
|
133
133
|
pre_pos = scanner.pos
|
134
134
|
|
135
135
|
loop do
|
@@ -146,10 +146,10 @@ module Acceptance
|
|
146
146
|
end
|
147
147
|
|
148
148
|
curr_pos = scanner.pos
|
149
|
-
return
|
149
|
+
return curr_pos != pre_pos
|
150
150
|
end
|
151
151
|
|
152
|
-
def skip_comment
|
152
|
+
def skip_comment
|
153
153
|
scanner.skip(/#[^\n\r]+/)
|
154
154
|
end
|
155
155
|
end # class
|
@@ -25,26 +25,26 @@ module Regex # Open this namespace, to get rid of scope qualifiers
|
|
25
25
|
|
26
26
|
context 'Creation & initialization' do
|
27
27
|
it 'should be created with a with an integer value (codepoint) or...' do
|
28
|
-
SampleInts.each do |
|
29
|
-
expect { Character.new(
|
28
|
+
SampleInts.each do |codepoint|
|
29
|
+
expect { Character.new(codepoint) }.not_to raise_error
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
33
|
it '...could be created with a single character String or...' do
|
34
|
-
SampleChars.each do |
|
35
|
-
expect { Character.new(
|
34
|
+
SampleChars.each do |ch|
|
35
|
+
expect { Character.new(ch) }.not_to raise_error
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
39
|
it '...could be created with an escape sequence' do
|
40
40
|
# Case 1: escape sequence is a digram
|
41
|
-
SampleDigrams.each do |
|
42
|
-
expect { Character.new(
|
41
|
+
SampleDigrams.each do |escape_seq|
|
42
|
+
expect { Character.new(escape_seq) }.not_to raise_error
|
43
43
|
end
|
44
44
|
|
45
45
|
# Case 2: escape sequence is an escaped octal or hexadecimal literal
|
46
|
-
SampleNumEscs.each do |
|
47
|
-
expect { Character.new(
|
46
|
+
SampleNumEscs.each do |escape_seq|
|
47
|
+
expect { Character.new(escape_seq) }.not_to raise_error
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end # context
|
@@ -52,15 +52,15 @@ module Regex # Open this namespace, to get rid of scope qualifiers
|
|
52
52
|
context 'Provided services' do
|
53
53
|
it 'Should know its lexeme if created from a string' do
|
54
54
|
# Lexeme is defined when the character was initialised from a text
|
55
|
-
SampleChars.each do |
|
56
|
-
ch = Character.new(
|
57
|
-
expect(ch.lexeme).to eq(
|
55
|
+
SampleChars.each do |ch|
|
56
|
+
ch = Character.new(ch)
|
57
|
+
expect(ch.lexeme).to eq(ch)
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
61
|
it 'Should not know its lexeme representation from a codepoint' do
|
62
|
-
SampleInts.each do |
|
63
|
-
ch = Character.new(
|
62
|
+
SampleInts.each do |ch|
|
63
|
+
ch = Character.new(ch)
|
64
64
|
expect(ch.lexeme).to be_nil
|
65
65
|
end
|
66
66
|
end
|
@@ -72,21 +72,21 @@ module Regex # Open this namespace, to get rid of scope qualifiers
|
|
72
72
|
expect(newOne.to_str).to eq("\u03A3")
|
73
73
|
|
74
74
|
# Try with our chars sample
|
75
|
-
SampleChars.each do |
|
76
|
-
new_ch = Character.new(
|
77
|
-
new_ch ==
|
75
|
+
SampleChars.each do |ch|
|
76
|
+
new_ch = Character.new(ch).to_str
|
77
|
+
new_ch == ch
|
78
78
|
end
|
79
79
|
|
80
80
|
# Try with our codepoint sample
|
81
|
-
mapped_chars = SampleInts.map do |
|
82
|
-
Character.new(
|
81
|
+
mapped_chars = SampleInts.map do |codepoint|
|
82
|
+
Character.new(codepoint).char
|
83
83
|
end
|
84
84
|
expect(mapped_chars).to eq(SampleChars)
|
85
85
|
|
86
86
|
# Try with our escape sequence samples
|
87
|
-
(SampleDigrams + SampleNumEscs).each do |
|
88
|
-
expectation = String.class_eval(%Q|"#{
|
89
|
-
new_ch = Character.new(
|
87
|
+
(SampleDigrams + SampleNumEscs).each do |escape_seq|
|
88
|
+
expectation = String.class_eval(%Q|"#{escape_seq}"|, __FILE__, __LINE__)
|
89
|
+
new_ch = Character.new(escape_seq).to_str
|
90
90
|
new_ch == expectation
|
91
91
|
end
|
92
92
|
end
|
@@ -97,20 +97,20 @@ module Regex # Open this namespace, to get rid of scope qualifiers
|
|
97
97
|
expect(newOne.codepoint).to eq(0x03a3)
|
98
98
|
|
99
99
|
# Try with our chars sample
|
100
|
-
allCodepoints = SampleChars.map do |
|
101
|
-
Character.new(
|
100
|
+
allCodepoints = SampleChars.map do |ch|
|
101
|
+
Character.new(ch).codepoint
|
102
102
|
end
|
103
103
|
expect(allCodepoints).to eq(SampleInts)
|
104
104
|
|
105
105
|
# Try with our codepoint sample
|
106
|
-
SampleInts.each do |
|
107
|
-
expect(Character.new(
|
106
|
+
SampleInts.each do |codepoint|
|
107
|
+
expect(Character.new(codepoint).codepoint).to eq(codepoint)
|
108
108
|
end
|
109
109
|
|
110
110
|
# Try with our escape sequence samples
|
111
|
-
(SampleDigrams + SampleNumEscs).each do |
|
112
|
-
expectation = String.class_eval(%Q|"#{
|
113
|
-
expect(Character.new(
|
111
|
+
(SampleDigrams + SampleNumEscs).each do |escape_seq|
|
112
|
+
expectation = String.class_eval(%Q|"#{escape_seq}".ord()|, __FILE__, __LINE__)
|
113
|
+
expect(Character.new(escape_seq).codepoint).to eq(expectation)
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
@@ -147,8 +147,8 @@ module Regex # Open this namespace, to get rid of scope qualifiers
|
|
147
147
|
|
148
148
|
# Create a module that re-defines the existing to_s method
|
149
149
|
module Tweak_to_s
|
150
|
-
def to_s
|
151
|
-
|
150
|
+
def to_s # Overwrite the existing to_s method
|
151
|
+
?\u03a3
|
152
152
|
end
|
153
153
|
end # module
|
154
154
|
weird = Object.new
|
@@ -9,8 +9,8 @@ module Regex # This module is used as a namespace
|
|
9
9
|
context 'Creation & initialisation' do
|
10
10
|
it 'should be created with 3 arguments' do
|
11
11
|
# Valid cases: initialized with two integer values and a policy symbol
|
12
|
-
%i[greedy lazy possessive].each do |
|
13
|
-
expect { Multiplicity.new(0, 1,
|
12
|
+
%i[greedy lazy possessive].each do |policy|
|
13
|
+
expect { Multiplicity.new(0, 1, policy) }.not_to raise_error
|
14
14
|
end
|
15
15
|
|
16
16
|
# Invalid case: initialized with invalid policy value
|
@@ -25,49 +25,49 @@ module Regex # This module is used as a namespace
|
|
25
25
|
policy2text = { greedy: '', lazy: '?', possessive: '+' }
|
26
26
|
|
27
27
|
# Case: zero or one
|
28
|
-
policy2text.each_key do |
|
29
|
-
multi = Multiplicity.new(0, 1,
|
30
|
-
expect(multi.to_str).to eq("?#{policy2text[
|
28
|
+
policy2text.each_key do |policy|
|
29
|
+
multi = Multiplicity.new(0, 1, policy)
|
30
|
+
expect(multi.to_str).to eq("?#{policy2text[policy]}")
|
31
31
|
end
|
32
32
|
|
33
33
|
# Case: zero or more
|
34
|
-
policy2text.each_key do |
|
35
|
-
multi = Multiplicity.new(0, :more,
|
36
|
-
expect(multi.to_str).to eq("*#{policy2text[
|
34
|
+
policy2text.each_key do |policy|
|
35
|
+
multi = Multiplicity.new(0, :more, policy)
|
36
|
+
expect(multi.to_str).to eq("*#{policy2text[policy]}")
|
37
37
|
end
|
38
38
|
|
39
39
|
# Case: one or more
|
40
|
-
policy2text.each_key do |
|
41
|
-
multi = Multiplicity.new(1, :more,
|
42
|
-
expect(multi.to_str).to eq("+#{policy2text[
|
40
|
+
policy2text.each_key do |policy|
|
41
|
+
multi = Multiplicity.new(1, :more, policy)
|
42
|
+
expect(multi.to_str).to eq("+#{policy2text[policy]}")
|
43
43
|
end
|
44
44
|
|
45
45
|
# Case: exactly m times
|
46
|
-
policy2text.each_key do |
|
46
|
+
policy2text.each_key do |policy|
|
47
47
|
samples = [1, 2, 5, 100]
|
48
|
-
samples.each do |
|
49
|
-
multi = Multiplicity.new(
|
50
|
-
expect(multi.to_str).to eq("{#{
|
48
|
+
samples.each do |count|
|
49
|
+
multi = Multiplicity.new(count, count, policy)
|
50
|
+
expect(multi.to_str).to eq("{#{count}}#{policy2text[policy]}")
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
54
|
# Case: m, n times
|
55
|
-
policy2text.each_key do |
|
55
|
+
policy2text.each_key do |policy|
|
56
56
|
samples = [1, 2, 5, 100]
|
57
|
-
samples.each do |
|
58
|
-
upper =
|
59
|
-
multi = Multiplicity.new(
|
60
|
-
expectation = "{#{
|
57
|
+
samples.each do |count|
|
58
|
+
upper = count + 1 + rand(20)
|
59
|
+
multi = Multiplicity.new(count, upper, policy)
|
60
|
+
expectation = "{#{count},#{upper}}#{policy2text[policy]}"
|
61
61
|
expect(multi.to_str).to eq(expectation)
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
65
|
# Case: m or more
|
66
|
-
policy2text.each_key do |
|
66
|
+
policy2text.each_key do |policy|
|
67
67
|
samples = [2, 3, 5, 100]
|
68
|
-
samples.each do |
|
69
|
-
multi = Multiplicity.new(
|
70
|
-
expect(multi.to_str).to eq("{#{
|
68
|
+
samples.each do |count|
|
69
|
+
multi = Multiplicity.new(count, :more, policy)
|
70
|
+
expect(multi.to_str).to eq("{#{count},}#{policy2text[policy]}")
|
71
71
|
end
|
72
72
|
end
|
73
73
|
end
|
data/srl_ruby.gemspec
CHANGED
@@ -17,13 +17,16 @@ module PkgExtending
|
|
17
17
|
'LICENSE.txt',
|
18
18
|
'README.md',
|
19
19
|
'srl_ruby.gemspec',
|
20
|
-
'
|
21
|
-
'
|
22
|
-
'spec/**/*.rb',
|
20
|
+
'bin/*.srl',
|
21
|
+
'bin/*.rb',
|
23
22
|
'features/*.*',
|
24
23
|
'features/**/*.*',
|
25
24
|
'features/**/**/*.features',
|
26
|
-
'
|
25
|
+
'lib/*.*',
|
26
|
+
'lib/**/*.rb',
|
27
|
+
'spec/**/*.rb',
|
28
|
+
'srl_test/**/*.*',
|
29
|
+
'templates/*.erb'
|
27
30
|
]
|
28
31
|
aPackage.files = file_list
|
29
32
|
aPackage.test_files = Dir['spec/**/*_spec.rb']
|
@@ -56,7 +59,7 @@ SUMMARY
|
|
56
59
|
spec.license = 'MIT'
|
57
60
|
|
58
61
|
spec.bindir = 'bin'
|
59
|
-
spec.executables << '
|
62
|
+
spec.executables << 'srl2ruby'
|
60
63
|
spec.require_paths = ['lib']
|
61
64
|
PkgExtending.pkg_files(spec)
|
62
65
|
PkgExtending.pkg_documentation(spec)
|
data/templates/base.erb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
<% # srl_and_ruby.erb: Outputs the SRL expression in comment, then the Ruby Regexp %>
|
2
|
+
# SRL expression follows:
|
3
|
+
<% srl_lines = srl_source.split(/(?:\r\n)|\n/)%>
|
4
|
+
<% srl_lines.each do |line| %>
|
5
|
+
<%= '# ' + line + "\n" %>
|
6
|
+
<% end %>
|
7
|
+
#
|
8
|
+
# ... and its Regexp equivalent:
|
9
|
+
/<%= (regexp.to_s =~ /\(\?\-mix/) ? regexp.source : regexp.to_s %>/
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<% # srl_and_ruby.erb: Outputs the SRL expression in block comment, then the Ruby Regexp %>
|
2
|
+
# SRL expression follows:
|
3
|
+
=begin
|
4
|
+
<% srl_lines = srl_source.split(/(?:\r\n)|\n/)%>
|
5
|
+
<% srl_lines.each do |line| %>
|
6
|
+
<%= ' ' + line + "\n" %>
|
7
|
+
<% end %>
|
8
|
+
=end
|
9
|
+
# ... and its Regexp equivalent:
|
10
|
+
/<%= (regexp.to_s =~ /\(\?\-mix/) ? regexp.source : regexp.to_s %>/
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: srl_ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dimitri Geshef
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-05-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rley
|
@@ -86,7 +86,7 @@ description: |2
|
|
86
86
|
email:
|
87
87
|
- famished.tiger@yahoo.com
|
88
88
|
executables:
|
89
|
-
-
|
89
|
+
- srl2ruby
|
90
90
|
extensions: []
|
91
91
|
extra_rdoc_files:
|
92
92
|
- README.md
|
@@ -100,7 +100,8 @@ files:
|
|
100
100
|
- README.md
|
101
101
|
- Rakefile
|
102
102
|
- appveyor.yml
|
103
|
-
- bin/
|
103
|
+
- bin/srl2ruby
|
104
|
+
- bin/srl2ruby_cli_parser.rb
|
104
105
|
- cucumber.yml
|
105
106
|
- features/basic/anchors.feature
|
106
107
|
- features/basic/characters.feature
|
@@ -183,6 +184,9 @@ files:
|
|
183
184
|
- srl_test/Test-Rules/website_example_password.rule
|
184
185
|
- srl_test/Test-Rules/website_example_url.rule
|
185
186
|
- srl_test/Test-Rules/word.rule
|
187
|
+
- templates/base.erb
|
188
|
+
- templates/srl_and_ruby.erb
|
189
|
+
- templates/srl_block_and_ruby.erb
|
186
190
|
homepage: https://github.com/famished-tiger/SRL-Ruby
|
187
191
|
licenses:
|
188
192
|
- MIT
|
data/bin/srl_ruby
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
require_relative '../lib/srl_ruby'
|
3
|
-
|
4
|
-
my_name = File.basename(__FILE__)
|
5
|
-
my_version = SrlRuby::VERSION
|
6
|
-
puts "#{my_name} v. #{my_version}"
|
7
|
-
|
8
|
-
# Parse the input expression in command-line
|
9
|
-
if ARGV.empty?
|
10
|
-
msg = <<-MSG
|
11
|
-
Simple Regex Language compiler:
|
12
|
-
- Parses an SRL expression and displays the corresponding Regexp literal
|
13
|
-
|
14
|
-
Command-line syntax (I):
|
15
|
-
========================
|
16
|
-
#{my_name} "SRL expression"
|
17
|
-
where:
|
18
|
-
the SRL expression is enclosed between double quotes (")
|
19
|
-
|
20
|
-
Examples:
|
21
|
-
#{my_name} "letter from a to f exactly 4 times"
|
22
|
-
#{my_name} "uppercase letter between 2 and 3 times"
|
23
|
-
#{my_name} "digit from 0 to 7 once or more"
|
24
|
-
|
25
|
-
Command-line syntax (II):
|
26
|
-
========================
|
27
|
-
#{my_name} -f filename
|
28
|
-
where:
|
29
|
-
the filename is a text file containing the SRL expression to compile
|
30
|
-
|
31
|
-
Examples:
|
32
|
-
#{my_name} -f hexadecimal.srl
|
33
|
-
MSG
|
34
|
-
puts msg
|
35
|
-
exit(1)
|
36
|
-
end
|
37
|
-
|
38
|
-
|
39
|
-
if ARGV[0] =~ /^--?fi?l?e?$/
|
40
|
-
srl_file = ARGV[1]
|
41
|
-
result = SrlRuby.load_file(srl_file)
|
42
|
-
else
|
43
|
-
srl_expr = ARGV[0]
|
44
|
-
puts 'SRL input: ' + srl_expr
|
45
|
-
result = SrlRuby.parse(srl_expr)
|
46
|
-
end
|
47
|
-
|
48
|
-
puts 'Resulting Regexp: /' + result.to_s + '/'
|
49
|
-
|
50
|
-
|
51
|
-
# End of file
|