grammar 0.5 → 0.8

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,19 @@
1
+
2
+ require 'grammar/ruby'
3
+ require 'rubygems'
4
+ require 'ruby2cext/eval2c'
5
+
6
+ class Grammar
7
+ class Ruby2CExt < Ruby
8
+
9
+ def self.compile(gram)
10
+ code = new.dump(gram)
11
+ #p(code)
12
+ #code.lined
13
+ Ruby2CExtension::Eval2C.new.compile_to_proc(code.to_s).call.new
14
+ end
15
+
16
+ end
17
+ end
18
+
19
+
@@ -0,0 +1,21 @@
1
+
2
+ require 'grammar/ruby'
3
+ require 'rubygems'
4
+
5
+ class Grammar
6
+ class RubyCall < Ruby
7
+
8
+ def self.compile(gram)
9
+ code = new.dump(gram)
10
+ #p(code)
11
+ #code.lined
12
+ eval(code.to_s).new
13
+ end
14
+ def recurse(inner, expand=false, &outer) # :yield: engine
15
+ expand ? super : call(inner, &outer)
16
+ end
17
+
18
+ end
19
+ end
20
+
21
+
@@ -0,0 +1,105 @@
1
+ #!/bin/env ruby
2
+
3
+ require 'stringio'
4
+
5
+ require 'grammar'
6
+
7
+ class Grammar
8
+ module Test
9
+ module Advanced
10
+ include Grammar::Molecules
11
+
12
+ def test_positive
13
+ comp = engine.compile(+E(?a) + E(?a..?z))
14
+ assert(comp[out="", StringIO.new("ab").method(:getc)])
15
+ assert_equal("a", out)
16
+ assert_raise(error) { comp[out="", lambda { ?b }] }
17
+ assert_equal("", out)
18
+ end
19
+
20
+ def test_negative
21
+ comp = engine.compile(-E(?a) + E(?a..?z))
22
+ assert(comp[out="", StringIO.new("ba").method(:getc)])
23
+ assert_equal("b", out)
24
+ assert_raise(error) { comp[out="", lambda { ?a }] }
25
+ assert_equal("", out)
26
+ end
27
+
28
+ def test_redirect
29
+ comp = engine.compile((E(?a)+E(?b)).redirect("") { |buf, eng|
30
+ eng << buf.reverse
31
+ })
32
+ assert(comp[out=[], StringIO.new("ab").method(:getc)])
33
+ assert_equal(["ba"], out)
34
+ end
35
+
36
+ def test_discard
37
+ comp = engine.compile(E(?a).discard+E(?b))
38
+ assert(comp[out="", StringIO.new("abb").method(:getc)])
39
+ assert_equal("b", out)
40
+ assert_raise(error) { comp[out="", lambda {?b}] }
41
+ assert_equal("", out)
42
+ comp = engine.compile((E(?a)+E(?b)).discard { |e| e[:ab] } + E(?c))
43
+ assert(comp[out=[], StringIO.new("abca").method(:getc)])
44
+ assert_equal([:ab,?c], out)
45
+ assert_raise(error) {
46
+ comp[out=[], StringIO.new("a").method(:getc)]
47
+ }
48
+ assert_equal([], out)
49
+ end
50
+
51
+ #def test_backref
52
+ # comp = engine.compile(E(?a)+(E(?b)+E(?c)).backref { |n, engine|
53
+ # engine.output[-n,n] = engine.output[-n,n].reverse
54
+ # } + E(?d))
55
+ # assert(comp[out="", StringIO.new("abcdab").method(:getc)])
56
+ # assert_equal("acbd", out)
57
+ # assert_raise(error) {
58
+ # comp[out="", StringIO.new("ab").method(:getc)]
59
+ # }
60
+ # assert_equal("a", out)
61
+ #end
62
+
63
+ def test_backtrack
64
+ comp = engine.compile((E(?a)+E(?b)).backtrack|(E(?a)+E(?c)))
65
+ assert(comp[out="", StringIO.new("abac").method(:getc)])
66
+ assert_equal("ab", out)
67
+ assert(comp[out="", StringIO.new("ac").method(:getc)])
68
+ assert_equal("ac", out)
69
+ end
70
+
71
+ def test_supply
72
+ token = (E(?a)|E(?b)).redirect("") { |buf, eng|
73
+ eng << buf.capitalize.to_sym
74
+ }
75
+ parser = E(:A) + E(:B)
76
+ leftover = nil
77
+ # TODO: leftover
78
+ comp = engine.compile(token.supply(parser, [])) # { |l, eng| leftover = l}
79
+ assert(comp[out=[], StringIO.new("abba").method(:getc)])
80
+ assert_equal([:A, :B], out)
81
+ #assert_equal([:B], leftover)
82
+ assert_raise(error) { comp[out=[], lambda {?a}] }
83
+ assert_equal([:A], out)
84
+ end
85
+
86
+ def test_pipe
87
+ lexer = Recurse { |g| g + (E(?a)|E(?b)).redirect("") { |buf, eng|
88
+ eng << buf.capitalize.to_sym
89
+ } | NULL }
90
+ parser = E(:A) + E(:B)
91
+ leftover = nil
92
+ # TODO: leftover
93
+ comp = engine.compile(lexer.pipe(parser, [], 1)) # { |l, eng| leftover = l})
94
+ assert(comp[out=[], StringIO.new("abbba").method(:getc)])
95
+ assert_equal([:A, :B], out)
96
+ #assert_equal([:B, :B], leftover)
97
+ assert_raise(error) { comp[out=[], lambda {?a}] }
98
+ assert_equal([:A], out)
99
+ end
100
+
101
+ end
102
+ end
103
+ end
104
+
105
+
@@ -0,0 +1,77 @@
1
+ #!/bin/env ruby
2
+
3
+ require 'stringio'
4
+
5
+ require 'grammar'
6
+
7
+ class Grammar
8
+ module Test
9
+ module Atoms
10
+ include Grammar::Molecules
11
+
12
+ def test_Grammar
13
+ gram = Grammar { |eng| eng[true] }
14
+ comp = engine.compile(gram)
15
+ assert(comp[out="", lambda {}])
16
+ assert_equal("", out)
17
+ gram << E(?a)
18
+ comp = engine.compile(gram)
19
+ assert(comp[out="", lambda {?a}])
20
+ assert_equal("a", out)
21
+ assert_raise(error) {
22
+ comp[out="", lambda {}]
23
+ }
24
+ assert_equal("", out)
25
+ end
26
+
27
+ def test_Element
28
+ comp = engine.compile(Element(?a))
29
+ assert(comp[out="", StringIO.new("abc").method(:getc)])
30
+ assert_equal("a", out)
31
+ assert_raise(error) {
32
+ comp[out="", StringIO.new("bc").method(:getc)]
33
+ }
34
+ assert_equal("", out)
35
+ comp = engine.compile(E(?a..?z))
36
+ assert(comp[out="", StringIO.new("bc").method(:getc)])
37
+ assert_equal("b", out)
38
+ end
39
+
40
+ def test_Fail
41
+ out = ""
42
+ comp = engine.compile(Fail("TESTING"))
43
+ assert_raise(error) { comp[out, lambda {}] }
44
+ assert_equal("", out)
45
+ assert_raise(error) { comp[out="", lambda { ?a }] }
46
+ assert_equal("", out)
47
+ end
48
+
49
+ def test_NULL
50
+ comp = engine.compile(NULL)
51
+ comp[out="", lambda {}]
52
+ assert_equal("", out)
53
+ comp[out="", lambda { ?a }]
54
+ assert_equal("", out)
55
+ end
56
+
57
+ def test_ANY
58
+ comp = engine.compile(ANY)
59
+ comp[out="", lambda { ?a }]
60
+ assert_equal("a", out)
61
+ assert_raise(error) { comp[out="", lambda { }] }
62
+ assert_equal("", out)
63
+ end
64
+
65
+ def test_EOF
66
+ comp = engine.compile(EOF)
67
+ comp[out="", lambda {}]
68
+ assert_equal("", out)
69
+ assert_raise(error) { comp[out="", lambda { ?a }] }
70
+ assert_equal("", out)
71
+ end
72
+
73
+ end
74
+ end
75
+ end
76
+
77
+
@@ -0,0 +1,32 @@
1
+ #!/bin/env ruby
2
+
3
+ require 'stringio'
4
+
5
+ require 'grammar'
6
+
7
+ class Grammar
8
+ module Test
9
+ module Basic
10
+ include Grammar::Molecules
11
+
12
+ def test_plus
13
+ comp = engine.compile(E(?a)+E(?a..?z))
14
+ assert(comp[out="", StringIO.new("ab").method(:getc)])
15
+ assert_equal("ab", out)
16
+ end
17
+
18
+ def test_or
19
+ comp = engine.compile(E(?a)|E(?b))
20
+ assert(comp[out="", StringIO.new("abc").method(:getc)])
21
+ assert_equal("a", out)
22
+ assert(comp[out="", StringIO.new("bc").method(:getc)])
23
+ assert_equal("b", out)
24
+ assert_raise(error) { comp[out="", StringIO.new("c").method(:getc)] }
25
+ assert_equal("", out)
26
+ end
27
+
28
+ end
29
+ end
30
+ end
31
+
32
+
@@ -0,0 +1,147 @@
1
+ #!/bin/env ruby
2
+
3
+ require 'stringio'
4
+
5
+ require 'grammar'
6
+
7
+ class Grammar
8
+ module Test
9
+ module Composite
10
+ include Grammar::Molecules
11
+
12
+ def test_Check
13
+ comp = engine.compile(Check {|eng| eng[1]+eng[2]==eng[3]})
14
+ assert(comp[out="", lambda {}])
15
+ comp = engine.compile(Check {|eng| eng[1]+eng[1]==eng[1]})
16
+ assert_raise(error) { comp[out="", lambda {}] }
17
+ end
18
+
19
+ def test_not
20
+ comp = engine.compile(~E(?a..?z))
21
+ assert(comp[out="", lambda { ?A }])
22
+ assert_equal("A", out)
23
+ assert_raise(error) { comp[out="", lambda { ?a }] }
24
+ assert_equal("", out)
25
+ end
26
+
27
+ def test_optional
28
+ comp = engine.compile(E(?a).optional)
29
+ assert(comp[out="", StringIO.new("ab").method(:getc)])
30
+ assert_equal("a", out)
31
+ assert(comp[out="", StringIO.new("b").method(:getc)])
32
+ assert_equal("", out)
33
+ end
34
+
35
+ def test_repeat0
36
+ comp = engine.compile(E(?a).repeat0)
37
+ assert(comp[out="", lambda { }])
38
+ assert_equal("", out)
39
+ assert(comp[out="", StringIO.new("a").method(:getc)])
40
+ assert_equal("a", out)
41
+ assert(comp[out="", StringIO.new("aaa").method(:getc)])
42
+ assert_equal("aaa", out)
43
+ comp = engine.compile(E(?a).repeat0(E(?b)))
44
+ assert(comp[out="", StringIO.new("babaaab").method(:getc)])
45
+ assert_equal("b", out)
46
+ assert(comp[out="", StringIO.new("abaaab").method(:getc)])
47
+ assert_equal("ab", out)
48
+ assert(comp[out="", StringIO.new("aaab").method(:getc)])
49
+ assert_equal("aaab", out)
50
+ end
51
+
52
+ def test_repeat1
53
+ comp = engine.compile(E(?a).repeat1)
54
+ out = ""
55
+ assert_raise(error) { comp[out, lambda { }] }
56
+ assert_equal("", out)
57
+ assert(comp[out="", StringIO.new("a").method(:getc)])
58
+ assert_equal("a", out)
59
+ assert(comp[out="", StringIO.new("aaa").method(:getc)])
60
+ assert_equal("aaa", out)
61
+ comp = engine.compile(E(?a).repeat1(E(?b)))
62
+ assert(comp[out="", StringIO.new("abaaabb").method(:getc)])
63
+ assert_equal("ab", out)
64
+ assert(comp[out="", StringIO.new("aaabb").method(:getc)])
65
+ assert_equal("aaab", out)
66
+ assert_raise(error) {
67
+ comp[out="", StringIO.new("b").method(:getc)]
68
+ }
69
+ assert_equal("", out)
70
+ end
71
+
72
+ def test_times_Fixnum
73
+ comp = engine.compile(E(?a)*2)
74
+ assert(comp[out="", StringIO.new("aab").method(:getc)])
75
+ assert_equal("aa", out)
76
+ assert(comp[out="", StringIO.new("aaa").method(:getc)])
77
+ assert_equal("aa", out)
78
+ assert_raise(error) {
79
+ comp[out="", StringIO.new("b").method(:getc)]
80
+ }
81
+ assert_equal("", out)
82
+ assert_raise(error) {
83
+ comp[out="", StringIO.new("ab").method(:getc)]
84
+ }
85
+ assert_equal("a", out)
86
+ end
87
+
88
+ def test_times_Range
89
+ comp = engine.compile(E(?a)*(1..2))
90
+ assert(comp[out="", StringIO.new("aaab").method(:getc)])
91
+ assert_equal("aa", out)
92
+ assert(comp[out="", StringIO.new("ab").method(:getc)])
93
+ assert_equal("a", out)
94
+ assert_raise(error) {
95
+ comp[out="", StringIO.new("b").method(:getc)]
96
+ }
97
+ assert_equal("", out)
98
+ end
99
+
100
+ def test_times_Range1Inf
101
+ comp = engine.compile(E(?a)*(1..1.0/0)+E(?b))
102
+ assert(comp[out="", StringIO.new("abaaaba").method(:getc)])
103
+ assert_equal("ab", out)
104
+ assert(comp[out="", StringIO.new("aaaba").method(:getc)])
105
+ assert_equal("aaab", out)
106
+ assert_raise(error) {
107
+ comp[out="", StringIO.new("a").method(:getc)]
108
+ }
109
+ assert_equal("a", out)
110
+ assert_raise(error) {
111
+ comp[out="", StringIO.new("babaaaba").method(:getc)]
112
+ }
113
+ assert_equal("", out)
114
+ end
115
+
116
+ def test_times_Range0Inf
117
+ comp = engine.compile(E(?a)*(0..1.0/0)+E(?b))
118
+ assert(comp[out="", StringIO.new("babaaaba").method(:getc)])
119
+ assert_equal("b", out)
120
+ assert(comp[out="", StringIO.new("abaaaba").method(:getc)])
121
+ assert_equal("ab", out)
122
+ assert(comp[out="", StringIO.new("aaaba").method(:getc)])
123
+ assert_equal("aaab", out)
124
+ assert_raise(error) {
125
+ comp[out="", StringIO.new("a").method(:getc)]
126
+ }
127
+ assert_equal("a", out)
128
+ end
129
+
130
+ def test_group
131
+ comp = engine.compile((E(?a)+E(?b)).group("") + E(?c))
132
+ assert(comp[out=[], StringIO.new("abca").method(:getc)])
133
+ assert_equal(["ab",?c], out)
134
+ assert_raise(error) {
135
+ comp[out=[], StringIO.new("a").method(:getc)]
136
+ }
137
+ assert_equal([], out)
138
+ comp = engine.compile(E(?0..?9).repeat1.group("") { |buf, eng| buf.to_i })
139
+ assert(comp[out=[], StringIO.new("123").method(:getc)])
140
+ assert_equal([123], out)
141
+ end
142
+
143
+ end
144
+ end
145
+ end
146
+
147
+
@@ -0,0 +1,125 @@
1
+ #!/bin/env ruby
2
+
3
+ require 'stringio'
4
+
5
+ require 'grammar'
6
+
7
+ class Grammar
8
+ module Test
9
+ module Molecules
10
+ include Grammar::Molecules
11
+
12
+ def test_Variables
13
+ comp = engine.compile(Variables(true) { |var| Check { var[] } })
14
+ assert(comp[out="", lambda {}])
15
+ assert_equal("", out)
16
+ comp = engine.compile(Variables(false) { |found|
17
+ (E(?a) + Grammar { |engine| found << engine[true] } | NULL) +
18
+ (Grammar { found[] } + E(?b) | E(?z))
19
+ })
20
+ assert(comp[out="", StringIO.new("abz").method(:getc)])
21
+ assert_equal("ab", out)
22
+ assert(comp[out="", lambda { ?z }])
23
+ assert_equal("z", out)
24
+ assert_raise(error) { comp[out="", lambda { ?b }] }
25
+ end
26
+
27
+ def test_Recurse_middle
28
+ comp = engine.compile(Recurse { |gram| E(?() + gram + E(?)) | NULL })
29
+ assert(comp[out="", StringIO.new("()(())(").method(:getc)])
30
+ assert_equal("()", out)
31
+ assert(comp[out="", StringIO.new("(())(").method(:getc)])
32
+ assert_equal("(())", out)
33
+ assert_raise(error) {
34
+ comp[out="", StringIO.new("(").method(:getc)]
35
+ }
36
+ assert_equal("(", out)
37
+ assert(comp[out="", lambda {}])
38
+ assert_equal("", out)
39
+ comp = engine.compile(Recurse { |gram| E(?() + gram + E(?)) | E(?a) })
40
+ assert(comp[out="", StringIO.new("a(a)((a))((ab").method(:getc)])
41
+ assert_equal("a", out)
42
+ assert(comp[out="", StringIO.new("(a)((a))((ab").method(:getc)])
43
+ assert_equal("(a)", out)
44
+ assert(comp[out="", StringIO.new("((a))((ab").method(:getc)])
45
+ assert_equal("((a))", out)
46
+ assert_raise(error) {
47
+ comp[out="", StringIO.new("((ab").method(:getc)]
48
+ }
49
+ assert_equal("((a", out)
50
+ end
51
+
52
+ def test_Recurse_right
53
+ comp = engine.compile(Recurse { |gram| E(?a)+gram | NULL })
54
+ assert(comp[out="", lambda {}])
55
+ assert_equal("", out)
56
+ assert(comp[out="", StringIO.new("a").method(:getc)])
57
+ assert_equal("a", out)
58
+ assert(comp[out="", StringIO.new("aaa").method(:getc)])
59
+ assert_equal("aaa", out)
60
+ comp = engine.compile(Recurse { |gram| E(?a) + (E(?b)|gram) })
61
+ assert(comp[out="", StringIO.new("abaaaba").method(:getc)])
62
+ assert_equal("ab", out)
63
+ assert(comp[out="", StringIO.new("aaaba").method(:getc)])
64
+ assert_equal("aaab", out)
65
+ assert_raise(error) {
66
+ comp[out="", StringIO.new("a").method(:getc)]
67
+ }
68
+ assert_equal("a", out)
69
+ assert_raise(error) { comp[out="", lambda { ?b }] }
70
+ assert_equal("", out)
71
+ comp = engine.compile(Recurse { |gram| E(?a) + (E(?b)|gram) } | E(?b))
72
+ assert(comp[out="", StringIO.new("baaaba").method(:getc)])
73
+ assert_equal("b", out)
74
+ assert(comp[out="", StringIO.new("aaaba").method(:getc)])
75
+ assert_equal("aaab", out)
76
+ assert_raise(error) {
77
+ comp[out="", StringIO.new("a").method(:getc)]
78
+ }
79
+ assert_equal("a", out)
80
+ end
81
+
82
+ def test_Recurse_left
83
+ comp = engine.compile(Recurse { |gram| gram+E(?a) | NULL })
84
+ assert(comp[out="", lambda {}])
85
+ assert_equal("", out)
86
+ assert(comp[out="", StringIO.new("a").method(:getc)])
87
+ assert_equal("a", out)
88
+ assert(comp[out="", StringIO.new("aaa").method(:getc)])
89
+ assert_equal("aaa", out)
90
+ comp = engine.compile(Recurse { |gram| gram+E(?a) | E(?b) })
91
+ assert(comp[out="", lambda { ?b }])
92
+ assert_equal("b", out)
93
+ assert(comp[out="", StringIO.new("ba").method(:getc)])
94
+ assert_equal("ba", out)
95
+ assert(comp[out="", StringIO.new("baaab").method(:getc)])
96
+ assert_equal("baaa", out)
97
+ #comp = engine.compile(Recurse { |gram| gram+NULL })
98
+ #assert_raise(error) {
99
+ # comp[out="", lambda { E(?a) }]
100
+ #}
101
+ #assert_equal("", out)
102
+ #comp = engine.compile(Recurse { |gram| gram })
103
+ #assert_raise(RuntimeError) {
104
+ # comp[out="", lambda { E(?a) }]
105
+ #}
106
+ #assert_equal("", out)
107
+ #comp = engine.compile(Recurse { |gram| gram+NULL | NULL })
108
+ #assert_raise(RuntimeError) {
109
+ # comp[out="", lambda { E(?a) }]
110
+ #}
111
+ #assert_equal("", out)
112
+ comp = engine.compile(Recurse { |gram| gram+E(?a)+E(?c) | E(?b) })
113
+ assert(comp[out="", StringIO.new("bacacbacab").method(:getc)])
114
+ assert_equal("bacac", out)
115
+ assert_raise(error) {
116
+ comp[out="", StringIO.new("bacab").method(:getc)]
117
+ }
118
+ assert_equal("baca", out)
119
+ end
120
+
121
+ end
122
+ end
123
+ end
124
+
125
+