grammar 0.5 → 0.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+