rly 0.2.2 → 0.2.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.
- data/lib/rly/helpers.rb +49 -0
- data/lib/rly/version.rb +1 -1
- data/spec/lex/lex_helpers_spec.rb +32 -0
- data/spec/parse/yacc_helpers_spec.rb +101 -0
- metadata +7 -2
data/lib/rly/helpers.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
module Rly
|
2
|
+
|
3
|
+
class Lex
|
4
|
+
def self.ignore_spaces_and_tabs
|
5
|
+
ignore " \t"
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.lex_number_tokens
|
9
|
+
token :NUMBER, /\d+/ do |t|
|
10
|
+
t.value = t.value.to_i
|
11
|
+
t
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.lex_double_quoted_string_tokens
|
16
|
+
token :STRING, /"[^"]*"/ do |t|
|
17
|
+
t.value = t.value[1...-1]
|
18
|
+
t
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class Yacc
|
24
|
+
def self.with_values
|
25
|
+
raise ArgumentError.new("Must pass a block") unless block_given?
|
26
|
+
->(*args) {
|
27
|
+
ret = args.shift
|
28
|
+
ret.value = yield *args.map { |a| a.value }
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.assign_rhs(idx=1)
|
33
|
+
->(*args) {
|
34
|
+
ret = args.shift
|
35
|
+
idx -= 1
|
36
|
+
ret.value = args[idx] ? args[idx].value : nil
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.collect_to_a
|
41
|
+
->(ret, val, *args) {
|
42
|
+
ret.value = [val.value]
|
43
|
+
vals = args[-1]
|
44
|
+
ret.value += vals.value if vals
|
45
|
+
}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
data/lib/rly/version.rb
CHANGED
@@ -0,0 +1,32 @@
|
|
1
|
+
require "rly"
|
2
|
+
require "rly/helpers"
|
3
|
+
|
4
|
+
describe "Rly::Lex Helpers" do
|
5
|
+
it "has a helper to use a common whitespace ignore pattern" do
|
6
|
+
testLexer = Class.new(Rly::Lex) do
|
7
|
+
ignore_spaces_and_tabs
|
8
|
+
end
|
9
|
+
|
10
|
+
expect { testLexer.new(" \t \t").next }.not_to raise_exception
|
11
|
+
end
|
12
|
+
|
13
|
+
it "has a helper to parse numeric tokens" do
|
14
|
+
testLexer = Class.new(Rly::Lex) do
|
15
|
+
lex_number_tokens
|
16
|
+
end
|
17
|
+
|
18
|
+
tok = testLexer.new("123").next
|
19
|
+
tok.type.should == :NUMBER
|
20
|
+
tok.value.should == 123
|
21
|
+
end
|
22
|
+
|
23
|
+
it "has a helper to parse double-quoted string tokens" do
|
24
|
+
testLexer = Class.new(Rly::Lex) do
|
25
|
+
lex_double_quoted_string_tokens
|
26
|
+
end
|
27
|
+
|
28
|
+
tok = testLexer.new('"a test"').next
|
29
|
+
tok.type.should == :STRING
|
30
|
+
tok.value.should == 'a test'
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require "rly"
|
2
|
+
require "rly/helpers"
|
3
|
+
|
4
|
+
describe "Rly::Yacc Helpers" do
|
5
|
+
it "has a helper to use a simpler syntax for action blocks" do
|
6
|
+
testParser = Class.new(Rly::Yacc) do
|
7
|
+
lexer do
|
8
|
+
token :VALUE, /[a-z]+/
|
9
|
+
end
|
10
|
+
|
11
|
+
rule 'statement : VALUE', &with_values { |v|
|
12
|
+
"stmt#{v}end"
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
p = testParser.new
|
17
|
+
p.parse("test").should == "stmttestend"
|
18
|
+
end
|
19
|
+
|
20
|
+
context "rhs value assignment" do
|
21
|
+
it "has a helper to assign first rhs value" do
|
22
|
+
testParser = Class.new(Rly::Yacc) do
|
23
|
+
lexer do
|
24
|
+
literals "[]"
|
25
|
+
token :VALUE, /[a-z]+/
|
26
|
+
end
|
27
|
+
|
28
|
+
rule 'statement : VALUE', &assign_rhs
|
29
|
+
end
|
30
|
+
|
31
|
+
p = testParser.new
|
32
|
+
p.parse("test").should == "test"
|
33
|
+
end
|
34
|
+
|
35
|
+
it "has a helper to assign one given rhs value" do
|
36
|
+
testParser = Class.new(Rly::Yacc) do
|
37
|
+
lexer do
|
38
|
+
literals "[]"
|
39
|
+
token :VALUE, /[a-z]+/
|
40
|
+
end
|
41
|
+
|
42
|
+
rule 'statement : "[" VALUE "]"', &assign_rhs(2)
|
43
|
+
end
|
44
|
+
|
45
|
+
p = testParser.new
|
46
|
+
p.parse("[test]").should == "test"
|
47
|
+
end
|
48
|
+
|
49
|
+
it "has a helper to assign first rhs value, assigning nil, if the value is not present" do
|
50
|
+
testParser = Class.new(Rly::Yacc) do
|
51
|
+
lexer do
|
52
|
+
literals "[]"
|
53
|
+
token :VALUE, /[a-z]+/
|
54
|
+
end
|
55
|
+
|
56
|
+
rule 'statements : statement statement' do |l, s1, s2|
|
57
|
+
l.value = [s1.value, s2.value]
|
58
|
+
end
|
59
|
+
|
60
|
+
rule 'statement : VALUE
|
61
|
+
|', &assign_rhs
|
62
|
+
end
|
63
|
+
|
64
|
+
p = testParser.new
|
65
|
+
p.parse("test").should == ["test", nil]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "collecting values to array" do
|
70
|
+
it "works with no separators" do
|
71
|
+
testParser = Class.new(Rly::Yacc) do
|
72
|
+
lexer do
|
73
|
+
ignore " "
|
74
|
+
token :VALUE, /[a-z]+/
|
75
|
+
end
|
76
|
+
|
77
|
+
rule 'values : VALUE
|
78
|
+
| VALUE values', &collect_to_a
|
79
|
+
end
|
80
|
+
|
81
|
+
p = testParser.new
|
82
|
+
p.parse("a b c").should == %w[a b c]
|
83
|
+
end
|
84
|
+
|
85
|
+
it "works, when there are separators between values" do
|
86
|
+
testParser = Class.new(Rly::Yacc) do
|
87
|
+
lexer do
|
88
|
+
literals ","
|
89
|
+
token :VALUE, /[a-z]+/
|
90
|
+
end
|
91
|
+
|
92
|
+
rule 'values : VALUE
|
93
|
+
| VALUE "," values', &collect_to_a
|
94
|
+
end
|
95
|
+
|
96
|
+
p = testParser.new
|
97
|
+
p.parse("a,b,c").should == %w[a b c]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rly
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -44,6 +44,7 @@ files:
|
|
44
44
|
- assets/ply_dump.erb
|
45
45
|
- lib/rly.rb
|
46
46
|
- lib/rly/file_lex.rb
|
47
|
+
- lib/rly/helpers.rb
|
47
48
|
- lib/rly/lex.rb
|
48
49
|
- lib/rly/lex_token.rb
|
49
50
|
- lib/rly/parse/grammar.rb
|
@@ -57,12 +58,14 @@ files:
|
|
57
58
|
- lib/rly/version.rb
|
58
59
|
- lib/rly/yacc.rb
|
59
60
|
- rly.gemspec
|
61
|
+
- spec/lex/lex_helpers_spec.rb
|
60
62
|
- spec/lex/lex_spec.rb
|
61
63
|
- spec/parse/calc_spec.rb
|
62
64
|
- spec/parse/grammar_spec.rb
|
63
65
|
- spec/parse/lr_table_spec.rb
|
64
66
|
- spec/parse/production_spec.rb
|
65
67
|
- spec/parse/rule_parser_spec.rb
|
68
|
+
- spec/parse/yacc_helpers_spec.rb
|
66
69
|
- spec/parse/yacc_spec.rb
|
67
70
|
- spec/spec_helper.rb
|
68
71
|
homepage: ''
|
@@ -90,12 +93,14 @@ signing_key:
|
|
90
93
|
specification_version: 3
|
91
94
|
summary: A simple ruby implementation of lex and yacc, based on Python's ply
|
92
95
|
test_files:
|
96
|
+
- spec/lex/lex_helpers_spec.rb
|
93
97
|
- spec/lex/lex_spec.rb
|
94
98
|
- spec/parse/calc_spec.rb
|
95
99
|
- spec/parse/grammar_spec.rb
|
96
100
|
- spec/parse/lr_table_spec.rb
|
97
101
|
- spec/parse/production_spec.rb
|
98
102
|
- spec/parse/rule_parser_spec.rb
|
103
|
+
- spec/parse/yacc_helpers_spec.rb
|
99
104
|
- spec/parse/yacc_spec.rb
|
100
105
|
- spec/spec_helper.rb
|
101
106
|
has_rdoc:
|