babel_bridge 0.4.1 → 0.5.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.
- data/Rakefile +6 -0
- data/lib/nodes.rb +1 -1
- data/lib/nodes/empty_node.rb +1 -20
- data/lib/nodes/node.rb +33 -32
- data/lib/nodes/non_terminal_node.rb +10 -13
- data/lib/nodes/root_node.rb +4 -0
- data/lib/nodes/rule_node.rb +97 -44
- data/lib/nodes/terminal_node.rb +3 -3
- data/lib/parser.rb +95 -61
- data/lib/pattern_element.rb +71 -43
- data/lib/rule.rb +12 -6
- data/lib/rule_variant.rb +39 -15
- data/lib/string.rb +2 -9
- data/lib/tools.rb +26 -6
- data/lib/version.rb +2 -1
- data/spec/advanced_parsers_spec.rb +49 -0
- data/spec/basic_parsing_spec.rb +94 -0
- data/spec/bb_spec.rb +7 -163
- data/spec/ignore_whitespace_spec.rb +227 -0
- data/spec/inspect_spec.rb +50 -0
- data/spec/many_spec.rb +60 -0
- data/spec/node_spec.rb +117 -0
- data/spec/pattern_generators_spec.rb +41 -0
- data/spec/rule_parsing_spec.rb +61 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/tools_spec.rb +21 -0
- metadata +13 -4
- data/lib/nodes/many_node.rb +0 -53
- data/test/test_bb.rb +0 -458
- data/test/test_helper.rb +0 -44
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "basic parsing" do
|
4
|
+
include TestParserGenerator
|
5
|
+
|
6
|
+
it "string literal should work" do
|
7
|
+
new_parser do
|
8
|
+
rule :foo, "foo"
|
9
|
+
end
|
10
|
+
|
11
|
+
test_parse "foo"
|
12
|
+
test_parse("foo").offset.should == 0
|
13
|
+
test_parse("foo").text.length.should == 3
|
14
|
+
end
|
15
|
+
|
16
|
+
it ".as option should work" do
|
17
|
+
new_parser do
|
18
|
+
rule :foo, match("foo").as(:boo)
|
19
|
+
end
|
20
|
+
|
21
|
+
test_parse "foo"
|
22
|
+
test_parse("foo").boo.text.should == "foo"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "regexp should work" do
|
26
|
+
new_parser do
|
27
|
+
rule :foo, /[0-9]+/
|
28
|
+
end
|
29
|
+
|
30
|
+
%w{ 0 1 10 123 1001 }.each do |numstr|
|
31
|
+
test_parse numstr
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# bb uses some regexp optimizations which could fail if not matched @ the first character of the source
|
36
|
+
it "regexp should work even when it isn't the first match" do
|
37
|
+
new_parser do
|
38
|
+
rule :foo, /[0-9]+/
|
39
|
+
rule :foo, "hi", /[0-9]+/
|
40
|
+
end
|
41
|
+
|
42
|
+
test_parse "123"
|
43
|
+
test_parse "hi123"
|
44
|
+
end
|
45
|
+
|
46
|
+
it "test optional" do
|
47
|
+
new_parser do
|
48
|
+
rule :foo, "foo", :bar?
|
49
|
+
rule :bar, "bar"
|
50
|
+
end
|
51
|
+
|
52
|
+
test_parse "foo"
|
53
|
+
test_parse "foobar"
|
54
|
+
end
|
55
|
+
|
56
|
+
it "test could" do
|
57
|
+
new_parser do
|
58
|
+
rule :foo, could.match(/[a-z]/), /[a-zA-Z]+/
|
59
|
+
end
|
60
|
+
test_parse "FOO", :should_fail_at => 0
|
61
|
+
test_parse "fOO"
|
62
|
+
test_parse "foo"
|
63
|
+
end
|
64
|
+
|
65
|
+
it "test optional in the middle" do
|
66
|
+
new_parser do
|
67
|
+
rule :foo, "foo", match?("bar"), "foo"
|
68
|
+
end
|
69
|
+
|
70
|
+
test_parse "foofoo"
|
71
|
+
test_parse "foobarfoo"
|
72
|
+
end
|
73
|
+
|
74
|
+
# this seems a little strange, but it is correct behavior for a Parsing-Expression-Grammar parser
|
75
|
+
it "test_greedy_optional_middle" do
|
76
|
+
new_parser do
|
77
|
+
rule :foo, "foo", match?("foo"), "foo"
|
78
|
+
end
|
79
|
+
|
80
|
+
test_parse "foofoo", :should_fail_at => 6
|
81
|
+
test_parse "foofoofoo"
|
82
|
+
end
|
83
|
+
|
84
|
+
it "! (not-match) should work" do
|
85
|
+
new_parser do
|
86
|
+
rule :foo, match!("boo"), /[a-zA-Z]+/
|
87
|
+
end
|
88
|
+
|
89
|
+
test_parse "boo", :should_fail_at => 0
|
90
|
+
test_parse "foo"
|
91
|
+
test_parse "boO"
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
data/spec/bb_spec.rb
CHANGED
@@ -1,44 +1,7 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe BabelBridge do
|
4
|
-
|
5
|
-
|
6
|
-
def new_parser(&block)
|
7
|
-
$parser_counter||=0
|
8
|
-
$parser_counter+=1
|
9
|
-
Object.const_set(klass_name="TestParser#{$parser_counter}",Class.new(BabelBridge::Parser,&block))
|
10
|
-
@parser=Object.const_get(klass_name).new
|
11
|
-
end
|
12
|
-
|
13
|
-
#options
|
14
|
-
# :parser
|
15
|
-
# :failure_ok
|
16
|
-
def test_parse(string,options={},&block)
|
17
|
-
parser = options[:parser] || @parser
|
18
|
-
res = parser.parse(string)
|
19
|
-
yield res if res && block
|
20
|
-
if options[:should_fail_at]
|
21
|
-
res.should == nil
|
22
|
-
parser.failure_index.should == options[:should_fail_at]
|
23
|
-
elsif !options[:failure_ok]
|
24
|
-
puts parser.parser_failure_info :verbose => true unless res
|
25
|
-
res.should_not == nil
|
26
|
-
end
|
27
|
-
res
|
28
|
-
end
|
29
|
-
|
30
|
-
it "ignore_whitespace should work" do
|
31
|
-
new_parser do
|
32
|
-
ignore_whitespace
|
33
|
-
rule :foobar, "foo", "bar"
|
34
|
-
end
|
35
|
-
|
36
|
-
test_parse "foobar"
|
37
|
-
test_parse "foo bar"
|
38
|
-
test_parse "foo \t \r \f \n bar"
|
39
|
-
test_parse " foobar"
|
40
|
-
test_parse "foobar "
|
41
|
-
end
|
4
|
+
include TestParserGenerator
|
42
5
|
|
43
6
|
it "the failure_index should be the furthest point reached, even if we managed to successfully match less" do
|
44
7
|
new_parser do
|
@@ -65,71 +28,6 @@ describe BabelBridge do
|
|
65
28
|
parser.parser_failure_info[partial_match_string].should == nil
|
66
29
|
end
|
67
30
|
|
68
|
-
it "include_whitespace should work" do
|
69
|
-
new_parser do
|
70
|
-
ignore_whitespace
|
71
|
-
|
72
|
-
rule :pair, :statement, :end_statement, :statement
|
73
|
-
rule :end_statement, rewind_whitespace, /([\t ]*[\n;])+/
|
74
|
-
rule :statement, "0"
|
75
|
-
end
|
76
|
-
|
77
|
-
test_parse "0;0"
|
78
|
-
test_parse "0\n0"
|
79
|
-
test_parse "0 ; 0"
|
80
|
-
test_parse "0 ; ; 0"
|
81
|
-
test_parse "0 \n 0"
|
82
|
-
test_parse "0 \n \n 0"
|
83
|
-
test_parse "0 \n ; \n 0"
|
84
|
-
test_parse "0 ; \n ;0"
|
85
|
-
test_parse "0 0", :should_fail_at => 1
|
86
|
-
end
|
87
|
-
|
88
|
-
it "include_whitespace should work even with EmptyNodes" do
|
89
|
-
new_parser do
|
90
|
-
ignore_whitespace
|
91
|
-
|
92
|
-
rule :pair, :statement, :end_statement, :statement
|
93
|
-
rule :end_statement, rewind_whitespace, /([\t ]*[\n;])+/
|
94
|
-
rule :statement, "0", :one?, :one?, :one?
|
95
|
-
rule :one, "1"
|
96
|
-
end
|
97
|
-
|
98
|
-
test_parse "0;0"
|
99
|
-
test_parse "01;0"
|
100
|
-
test_parse "0\n0"
|
101
|
-
test_parse "01\n0"
|
102
|
-
test_parse "011\n0"
|
103
|
-
test_parse "0111\n0"
|
104
|
-
end
|
105
|
-
|
106
|
-
it "include_whitespace should work with many" do
|
107
|
-
new_parser do
|
108
|
-
ignore_whitespace
|
109
|
-
rule :statements, many(:statement,:end_statement)
|
110
|
-
rule :end_statement, rewind_whitespace, /([\t ]*[;\n])+/
|
111
|
-
rule :statement, "0"
|
112
|
-
end
|
113
|
-
|
114
|
-
test_parse "0"
|
115
|
-
test_parse "0\n0"
|
116
|
-
end
|
117
|
-
|
118
|
-
it "custom ignore_whitespace should work" do
|
119
|
-
new_parser do
|
120
|
-
ignore_whitespace /[_\s]*/
|
121
|
-
|
122
|
-
rule :foobar, "foo", "bar"
|
123
|
-
end
|
124
|
-
|
125
|
-
test_parse "foobar"
|
126
|
-
test_parse "foo_bar"
|
127
|
-
test_parse "foo_ bar"
|
128
|
-
test_parse "foo _ bar"
|
129
|
-
test_parse "foo bar"
|
130
|
-
test_parse "foo-bar", :should_fail_at => 3
|
131
|
-
end
|
132
|
-
|
133
31
|
it "should work to have many-many parsing" do
|
134
32
|
new_parser do
|
135
33
|
rule :top, many(:bottom,";")
|
@@ -144,68 +42,14 @@ describe BabelBridge do
|
|
144
42
|
test_parse "0,0,0;0;0,0,0"
|
145
43
|
end
|
146
44
|
|
147
|
-
it "
|
45
|
+
it "if a name can be optionally matched more than one time, it should always be an array of matchs" do
|
148
46
|
new_parser do
|
149
|
-
|
150
|
-
rule :
|
151
|
-
rule :end_statement, rewind_whitespace, /([\t ]*[;\n])+/
|
152
|
-
rule :statement, :bin_op
|
153
|
-
binary_operators_rule :bin_op, :int, ["**", [:/, :*], [:+, "-"]], :right_operators => ["**"]
|
154
|
-
rule :int, /\d+/
|
155
|
-
end
|
156
|
-
|
157
|
-
test_parse "0"
|
158
|
-
test_parse <<ENDCODE
|
159
|
-
3+4
|
160
|
-
9-2
|
161
|
-
4
|
162
|
-
ENDCODE
|
163
|
-
end
|
164
|
-
|
165
|
-
it "should work to rewind_whitespace, :rule" do
|
166
|
-
new_parser do
|
167
|
-
ignore_whitespace
|
168
|
-
rule :all, :identifier, :parameter?, :identifier do
|
169
|
-
def to_model
|
170
|
-
[[identifier[0].to_sym, parameter && parameter.to_sym], identifier[1].to_sym]
|
171
|
-
end
|
172
|
-
end
|
173
|
-
rule :parameter, rewind_whitespace, /[ \t]*/, rewind_whitespace, :identifier
|
174
|
-
rule :identifier, /[_a-zA-Z][_a-zA-Z0-9]*/
|
175
|
-
end
|
176
|
-
|
177
|
-
test_parse("fred\nbar") {|parsed|parsed.to_model.should == [[:fred,nil],:bar]}
|
178
|
-
test_parse("fred foo\nbar") {|parsed|parsed.to_model.should == [[:fred,:foo],:bar]}
|
179
|
-
end
|
180
|
-
|
181
|
-
it "should work to rewind_whitespace, many" do
|
182
|
-
new_parser do
|
183
|
-
ignore_whitespace
|
184
|
-
rule :all, :identifier, :parameters?, :identifier do
|
185
|
-
def to_model
|
186
|
-
[[identifier[0].to_sym, parameters && parameters.to_s], identifier[1].to_sym]
|
187
|
-
end
|
188
|
-
end
|
189
|
-
rule :parameters, rewind_whitespace, /[ \t]*/, rewind_whitespace, many(:identifier,",")
|
190
|
-
rule :identifier, /[_a-zA-Z][_a-zA-Z0-9]*/
|
191
|
-
end
|
192
|
-
|
193
|
-
test_parse("fred\nbar") {|parsed| parsed.to_model.should==[[:fred,nil],:bar]}
|
194
|
-
test_parse("fred foo\nbar") {|parsed| parsed.to_model.should==[[:fred,"foo"],:bar]}
|
195
|
-
test_parse("fred foo, bar\nbar") {|parsed| parsed.to_model.should==[[:fred,"foo, bar"],:bar]}
|
196
|
-
end
|
197
|
-
|
198
|
-
it "dont.match shouldn't consume any whitespace" do
|
199
|
-
new_parser do
|
200
|
-
ignore_whitespace
|
201
|
-
rule :statements, :statement, "bar"
|
202
|
-
rule :statement, :identifier, :parameters?
|
203
|
-
rule :parameters, rewind_whitespace, / */, rewind_whitespace, :identifier
|
204
|
-
rule :identifier, dont.match("end"), /[_a-zA-Z][_a-zA-Z0-9]*/
|
47
|
+
rule :foo, :bar, :bar?
|
48
|
+
rule :bar, "bar"
|
205
49
|
end
|
206
50
|
|
207
|
-
test_parse("
|
208
|
-
test_parse("
|
51
|
+
test_parse("bar").bar.class.should == BabelBridge::MultiMatchesArray
|
52
|
+
test_parse("barbar").bar.class.should == BabelBridge::MultiMatchesArray
|
209
53
|
end
|
210
54
|
|
211
55
|
end
|
@@ -0,0 +1,227 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "ignore_whitespace" do
|
4
|
+
include TestParserGenerator
|
5
|
+
|
6
|
+
it "ignore_whitespace should work" do
|
7
|
+
new_parser do
|
8
|
+
ignore_whitespace
|
9
|
+
rule :foobar, "foo", "bar"
|
10
|
+
end
|
11
|
+
|
12
|
+
# test_parse "foobar"
|
13
|
+
# test_parse "foo bar"
|
14
|
+
# test_parse "foo \t \r \f \n bar"
|
15
|
+
# test_parse " foobar"
|
16
|
+
test_parse "foobar "
|
17
|
+
end
|
18
|
+
|
19
|
+
it "ignore_whitespace should work with many" do
|
20
|
+
new_parser do
|
21
|
+
ignore_whitespace
|
22
|
+
rule :foobar, many("foo")
|
23
|
+
end
|
24
|
+
|
25
|
+
test_parse "foo"
|
26
|
+
test_parse "foofoo"
|
27
|
+
test_parse "foo foo"
|
28
|
+
test_parse "foo foo\nfoo"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "custom delimiter should work" do
|
32
|
+
new_parser do
|
33
|
+
ignore_whitespace
|
34
|
+
rule :pair, "0", "0", :delimiter => /-*/
|
35
|
+
end
|
36
|
+
|
37
|
+
test_parse "00"
|
38
|
+
test_parse "0-0"
|
39
|
+
test_parse " 0-0"
|
40
|
+
test_parse " 0-0 "
|
41
|
+
test_parse " 0--0 "
|
42
|
+
end
|
43
|
+
|
44
|
+
it "custom // delimiter should work" do
|
45
|
+
new_parser do
|
46
|
+
ignore_whitespace
|
47
|
+
rule :pair, "0", "0", :delimiter => //
|
48
|
+
end
|
49
|
+
|
50
|
+
test_parse "00"
|
51
|
+
test_parse " 00"
|
52
|
+
test_parse " 00 "
|
53
|
+
test_parse "0 0", :should_fail_at => 1
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
it "custom delimiter should work" do
|
58
|
+
new_parser do
|
59
|
+
ignore_whitespace
|
60
|
+
|
61
|
+
rule :pair, :statement, :end_statement, :statement, :delimiter => //
|
62
|
+
rule :end_statement, /([\t ]*[\n;])+([\t ]*)?/
|
63
|
+
rule :statement, "0"
|
64
|
+
end
|
65
|
+
|
66
|
+
test_parse "0;0"
|
67
|
+
test_parse "0\n0"
|
68
|
+
test_parse "0 ; 0"
|
69
|
+
test_parse "0 ; ; 0"
|
70
|
+
test_parse "0 \n 0"
|
71
|
+
test_parse "0 \n \n 0"
|
72
|
+
test_parse "0 \n ; \n 0"
|
73
|
+
test_parse "0 ; \n ;0"
|
74
|
+
test_parse "0 0", :should_fail_at => 1
|
75
|
+
end
|
76
|
+
|
77
|
+
it "custom delimiters should work even with EmptyNodes" do
|
78
|
+
new_parser do
|
79
|
+
ignore_whitespace
|
80
|
+
|
81
|
+
rule :pair, :statement, :end_statement, :statement, :delimiter => //
|
82
|
+
rule :end_statement, /([\t ]*[\n;])+([\t ]*)?/
|
83
|
+
rule :statement, "0", :one?, :one?, :one?
|
84
|
+
rule :one, "1"
|
85
|
+
end
|
86
|
+
|
87
|
+
test_parse "0;0"
|
88
|
+
test_parse "01;0"
|
89
|
+
test_parse "0\n0"
|
90
|
+
test_parse "01\n0"
|
91
|
+
test_parse "011\n0"
|
92
|
+
test_parse "0111\n0"
|
93
|
+
end
|
94
|
+
|
95
|
+
it "custom delimiters should work with many" do
|
96
|
+
new_parser do
|
97
|
+
ignore_whitespace
|
98
|
+
rule :statements, many(:statement,:end_statement), :delimiter => //
|
99
|
+
rule :end_statement, /([\t ]*[\n;])+([\t ]*)?/
|
100
|
+
rule :statement, "0"
|
101
|
+
end
|
102
|
+
|
103
|
+
test_parse "0"
|
104
|
+
test_parse "0\n0"
|
105
|
+
test_parse "0\n0;0"
|
106
|
+
test_parse "0 0", :should_fail_at => 2
|
107
|
+
end
|
108
|
+
|
109
|
+
it "custom global delimiter should work" do
|
110
|
+
new_parser do
|
111
|
+
delimiter /[_\s]*/
|
112
|
+
|
113
|
+
rule :foobar, "foo", "bar"
|
114
|
+
end
|
115
|
+
|
116
|
+
test_parse "foobar"
|
117
|
+
test_parse "foo_bar"
|
118
|
+
test_parse "foo_ bar"
|
119
|
+
test_parse "foo _ bar"
|
120
|
+
test_parse "foo bar"
|
121
|
+
test_parse "foo-bar", :should_fail_at => 3
|
122
|
+
end
|
123
|
+
|
124
|
+
|
125
|
+
it "should work to rewind_whitespace, :rule" do
|
126
|
+
new_parser do
|
127
|
+
ignore_whitespace
|
128
|
+
rule :two, :statement, :statement do
|
129
|
+
def to_model
|
130
|
+
statement.map {|a|a.to_model}
|
131
|
+
end
|
132
|
+
end
|
133
|
+
rule :statement, :identifier, :parameter?, :delimiter => // do
|
134
|
+
def to_model
|
135
|
+
[identifier.to_sym, parameter && parameter.identifier.to_sym]
|
136
|
+
end
|
137
|
+
end
|
138
|
+
rule :parameter, /[ \t]*/, :identifier, :delimiter => //
|
139
|
+
rule :identifier, /[_a-zA-Z][_a-zA-Z0-9]*/
|
140
|
+
end
|
141
|
+
|
142
|
+
test_parse("fred\nbar") {|parsed|parsed.to_model.should == [[:fred,nil],[:bar,nil]]}
|
143
|
+
test_parse("fred foo\nbar") {|parsed|parsed.to_model.should == [[:fred,:foo],[:bar,nil]]}
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should work to have nested custom delimiters" do
|
147
|
+
new_parser do
|
148
|
+
ignore_whitespace
|
149
|
+
rule :all, :call, :call do
|
150
|
+
def to_model
|
151
|
+
call.collect &:to_model
|
152
|
+
end
|
153
|
+
end
|
154
|
+
rule :call, :identifier, :parameters?, :delimiter => // do
|
155
|
+
def to_model
|
156
|
+
[identifier.to_sym, parameters && parameters.to_s]
|
157
|
+
end
|
158
|
+
end
|
159
|
+
rule :parameters, /[ \t]*/, many(:identifier,","), :delimiter => //
|
160
|
+
rule :identifier, /[_a-zA-Z][_a-zA-Z0-9]*/
|
161
|
+
end
|
162
|
+
|
163
|
+
test_parse("fred\nbar") {|parsed| parsed.to_model.should==[[:fred,nil],[:bar,nil]]}
|
164
|
+
test_parse("fred foo\nbar") {|parsed| parsed.to_model.should==[[:fred," foo"],[:bar,nil]]}
|
165
|
+
test_parse("fred foo,bar\nbar") {|parsed| parsed.to_model.should==[[:fred," foo,bar"],[:bar,nil]]}
|
166
|
+
end
|
167
|
+
|
168
|
+
it "dont.match shouldn't consume any whitespace" do
|
169
|
+
new_parser do
|
170
|
+
ignore_whitespace
|
171
|
+
rule :statements, :statement, "bar"
|
172
|
+
rule :statement, :identifier, :parameters?, :delimiter => //
|
173
|
+
rule :parameters, / */, :identifier, :delimiter => //
|
174
|
+
rule :identifier, dont.match("end"), /[_a-zA-Z][_a-zA-Z0-9]*/
|
175
|
+
end
|
176
|
+
|
177
|
+
test_parse("fred\nbar")
|
178
|
+
#test_parse("fred foo\nbar")
|
179
|
+
end
|
180
|
+
|
181
|
+
it "delimiter should work" do
|
182
|
+
new_parser do
|
183
|
+
delimiter :custom_delimiter
|
184
|
+
rule :foobar, "foo", "bar"
|
185
|
+
rule :custom_delimiter, /-*/
|
186
|
+
end
|
187
|
+
|
188
|
+
test_parse "foobar"
|
189
|
+
test_parse "foo-bar"
|
190
|
+
test_parse "foo---bar"
|
191
|
+
end
|
192
|
+
|
193
|
+
it "should work to have many parsing with whitespace tricks" do
|
194
|
+
new_parser do
|
195
|
+
ignore_whitespace
|
196
|
+
#rule :statements, many(:statement,:end_statement), :delimiter => //
|
197
|
+
#rule :end_statement, /([\t ]*[;\n])+/
|
198
|
+
#rule :statement, :bin_op
|
199
|
+
binary_operators_rule :bin_op, :int, ["**", [:/, :*], [:+, "-"]], :right_operators => ["**"]
|
200
|
+
rule :int, /\d+/
|
201
|
+
end
|
202
|
+
|
203
|
+
=begin
|
204
|
+
NOTES: the problem is the post-parsing results method-missing methods don't work well.
|
205
|
+
|
206
|
+
If a named pattern is never matched, method-missing will fail. It should return nil.
|
207
|
+
If a named pattern may match 1 or more times, you will get back a singleton OR an array depending on the number of times.
|
208
|
+
|
209
|
+
I think the right answer is to drop method-missing entirely. Instead, when the rule is declared, create the accessor methods explicitly.
|
210
|
+
|
211
|
+
If a named pattern could match more than once, it will always return an array.
|
212
|
+
|
213
|
+
If it could match 0 times, it will work and return nil, if 0 times were indeed matched.
|
214
|
+
|
215
|
+
=end
|
216
|
+
test_parse "3"
|
217
|
+
=begin
|
218
|
+
test_parse "3+4"
|
219
|
+
test_parse <<ENDCODE
|
220
|
+
3+4
|
221
|
+
9-2
|
222
|
+
4
|
223
|
+
ENDCODE
|
224
|
+
=end
|
225
|
+
end
|
226
|
+
|
227
|
+
end
|