kpeg 0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,416 @@
1
+ require 'test/unit'
2
+ require 'kpeg'
3
+ require 'stringio'
4
+
5
+ class TestKPeg < Test::Unit::TestCase
6
+ def assert_match(m, str)
7
+ assert_kind_of KPeg::MatchString, m
8
+ assert_equal str, m.string
9
+ end
10
+
11
+ def test_dot
12
+ gram = KPeg.grammar do |g|
13
+ g.root = g.dot
14
+ end
15
+
16
+ assert_match KPeg.match("q", gram), "q"
17
+ end
18
+
19
+ def test_str
20
+ gram = KPeg.grammar do |g|
21
+ g.root = g.str("hello")
22
+ end
23
+
24
+ assert_match KPeg.match("hello", gram), "hello"
25
+ assert_equal nil, KPeg.match("vador", gram)
26
+ end
27
+
28
+ def test_reg
29
+ gram = KPeg.grammar do |g|
30
+ g.root = g.reg(/[0-9]/)
31
+ end
32
+
33
+ assert_match KPeg.match("3", gram), "3"
34
+ end
35
+
36
+ def test_char_range
37
+ gram = KPeg.grammar do |g|
38
+ g.root = g.range('0', '9')
39
+ end
40
+
41
+ assert_match KPeg.match("3", gram), "3"
42
+ end
43
+
44
+ def test_any
45
+ gram = KPeg.grammar do |g|
46
+ g.root = g.any g.str("hello"), g.str("chicken")
47
+ end
48
+
49
+ assert_match KPeg.match("hello", gram), "hello"
50
+ assert_match KPeg.match("chicken", gram), "chicken"
51
+ assert_equal nil, KPeg.match("vador", gram)
52
+ end
53
+
54
+ def test_maybe
55
+ gram = KPeg.grammar do |g|
56
+ g.root = g.maybe g.str("hello")
57
+ end
58
+
59
+ m = KPeg.match "hello", gram
60
+ assert_kind_of KPeg::Match, m
61
+ assert_equal 1, m.matches.size
62
+ assert_match m.matches[0], "hello"
63
+
64
+ m = KPeg.match "surprise", gram
65
+ assert_kind_of KPeg::Match, m
66
+ assert_equal 0, m.matches.size
67
+ end
68
+
69
+ def test_many
70
+ gram = KPeg.grammar do |g|
71
+ g.root = g.many g.str("run")
72
+ end
73
+
74
+ m = KPeg.match "runrunrun", gram
75
+ assert_kind_of KPeg::Match, m
76
+ assert_equal 3, m.matches.size
77
+ m.matches.each do |sm|
78
+ assert_match sm, "run"
79
+ end
80
+
81
+ assert_equal nil, KPeg.match("vador", gram)
82
+ end
83
+
84
+ def test_kleene
85
+ gram = KPeg.grammar do |g|
86
+ g.root = g.kleene g.str("run")
87
+ end
88
+
89
+ m = KPeg.match "runrunrun", gram
90
+ assert_kind_of KPeg::Match, m
91
+ assert_equal 3, m.matches.size
92
+ m.matches.each do |sm|
93
+ assert_match sm, "run"
94
+ end
95
+
96
+ m = KPeg.match "chicken", gram
97
+ assert_kind_of KPeg::Match, m
98
+ assert_equal 0, m.matches.size
99
+ end
100
+
101
+ def test_multiple
102
+ gram = KPeg.grammar do |g|
103
+ g.root = g.multiple g.str("run"), 2, 4
104
+ end
105
+
106
+ m = KPeg.match "runrun", gram
107
+ assert_kind_of KPeg::Match, m
108
+ assert_equal 2, m.matches.size
109
+ m.matches.each do |sm|
110
+ assert_match sm, "run"
111
+ end
112
+
113
+ m = KPeg.match "runrunrun", gram
114
+ assert_kind_of KPeg::Match, m
115
+ assert_equal 3, m.matches.size
116
+ m.matches.each do |sm|
117
+ assert_match sm, "run"
118
+ end
119
+
120
+ m = KPeg.match "runrunrunrun", gram
121
+ assert_kind_of KPeg::Match, m
122
+ assert_equal 4, m.matches.size
123
+ m.matches.each do |sm|
124
+ assert_match sm, "run"
125
+ end
126
+
127
+ assert_equal nil, KPeg.match("run", gram)
128
+ assert_equal nil, KPeg.match("runrunrunrunrun", gram)
129
+ assert_equal nil, KPeg.match("vador", gram)
130
+ end
131
+
132
+ def test_seq
133
+ gram = KPeg.grammar do |g|
134
+ g.root = g.seq g.str("hello"), g.str(", world")
135
+ end
136
+
137
+ m = KPeg.match "hello, world", gram
138
+ assert_kind_of KPeg::Match, m
139
+ assert_match m.matches[0], "hello"
140
+ assert_match m.matches[1], ", world"
141
+
142
+ assert_equal m.value, ["hello", ", world"]
143
+
144
+ assert_equal nil, KPeg.match("vador", gram)
145
+ assert_equal nil, KPeg.match("hello, vador", gram)
146
+ end
147
+
148
+ def test_andp
149
+ gram = KPeg.grammar do |g|
150
+ g.root = g.seq g.andp(g.str("h")), g.str("hello")
151
+ end
152
+
153
+ m = KPeg.match "hello", gram
154
+ assert_equal m.matches.size, 2
155
+ assert_match m.matches[0], ""
156
+ assert_match m.matches[1], "hello"
157
+ end
158
+
159
+ def test_notp
160
+ gram = KPeg.grammar do |g|
161
+ g.root = g.seq g.notp(g.str("g")), g.str("hello")
162
+ end
163
+
164
+ m = KPeg.match "hello", gram
165
+ assert_equal m.matches.size, 2
166
+ assert_match m.matches[0], ""
167
+ assert_match m.matches[1], "hello"
168
+ end
169
+
170
+ def test_ref
171
+ gram = KPeg.grammar do |g|
172
+ g.greeting = g.str("hello")
173
+ g.root = g.ref "greeting"
174
+ end
175
+
176
+ m = KPeg.match "hello", gram
177
+ assert_match m, "hello"
178
+ end
179
+
180
+ def test_invoke
181
+ gram = KPeg.grammar do |g|
182
+ g.greeting = g.str("hello")
183
+ g.root = g.invoke "greeting"
184
+ end
185
+
186
+ m = KPeg.match "hello", gram
187
+ assert_match m, "hello"
188
+ end
189
+
190
+ def test_foreign_ref
191
+ g1 = KPeg.grammar do |g|
192
+ g.greeting = "hello"
193
+ end
194
+
195
+ g2 = KPeg.grammar do |g|
196
+ g.root = g.ref("greeting", g1)
197
+ end
198
+
199
+ m = KPeg.match "hello", g2
200
+ assert_match m, "hello"
201
+ end
202
+
203
+ def test_foreign_ref_with_ref
204
+ g1 = KPeg.grammar do |g|
205
+ g.name = ", evan"
206
+ g.greeting = g.seq("hello", :name)
207
+ end
208
+
209
+ g2 = KPeg.grammar do |g|
210
+ g.root = g.ref("greeting", g1)
211
+ end
212
+
213
+ m = KPeg.match "hello, evan", g2
214
+ assert_match m.matches[0], "hello"
215
+ assert_match m.matches[1], ", evan"
216
+ end
217
+
218
+ def test_tag_with_name
219
+ gram = KPeg.grammar do |g|
220
+ g.root = g.seq(" ", g.t("hello", "greeting"))
221
+ end
222
+
223
+ m = KPeg.match " hello", gram
224
+
225
+ assert_equal 2, m.matches.size
226
+ tag = m.matches[1]
227
+ assert_kind_of KPeg::Tag, tag.op
228
+ assert_equal 1, tag.matches.size
229
+ assert_match tag.matches[0], "hello"
230
+
231
+ # show that tag influences the value of the sequence
232
+ assert_equal m.value, "hello"
233
+ end
234
+
235
+ def test_tag_without_name
236
+ gram = KPeg.grammar do |g|
237
+ g.root = g.seq(" ", g.t("hello"))
238
+ end
239
+
240
+ m = KPeg.match " hello", gram
241
+ assert_equal m.value, "hello"
242
+ end
243
+
244
+ def test_action
245
+ gram = KPeg.grammar do |g|
246
+ g.root = g.seq("hello", g.action("b + c"))
247
+ end
248
+
249
+ m = KPeg.match "hello", gram
250
+ assert_equal 2, m.matches.size
251
+ assert_match m.matches[0], "hello"
252
+
253
+ action = m.matches[1]
254
+ assert_equal action.op.action, "b + c"
255
+ end
256
+
257
+ def test_naming
258
+ gram = KPeg.grammar do |g|
259
+ g.greeting = g.str("hello")
260
+ g.root = g.greeting
261
+ end
262
+
263
+ m = KPeg.match "hello", gram
264
+ assert_match m, "hello"
265
+ end
266
+
267
+ def test_matching_curly
268
+ gram = KPeg.grammar do |g|
269
+ g.curly = g.seq("{", g.kleene(g.any(/[^{}]+/, :curly)), "}")
270
+ g.root = :curly
271
+ end
272
+
273
+ m = KPeg.match "{ hello }", gram
274
+ assert_match m.matches[0], "{"
275
+ assert_match m.matches[1].matches[0], " hello "
276
+ assert_match m.matches[2], "}"
277
+
278
+ parc = KPeg::Parser.new "{ foo { bar } }", gram
279
+ m = parc.parse
280
+ assert_equal "{ foo { bar } }", m.total_string
281
+
282
+ parc = KPeg::Parser.new "{ foo {\nbar }\n }", gram
283
+ m = parc.parse
284
+ assert_equal "{ foo {\nbar }\n }", m.total_string
285
+ end
286
+
287
+ def test_collect
288
+ gram = KPeg.grammar do |g|
289
+ g.root = g.collect(g.many(/[a-z]/))
290
+ end
291
+
292
+ m = KPeg.match "hellomatch", gram
293
+ assert_equal "hellomatch", m.value
294
+ end
295
+
296
+ def test_memoization
297
+ gram = KPeg.grammar do |g|
298
+ g.one = g.str("1")
299
+ g.two = g.str("2")
300
+
301
+ g.root = g.any(
302
+ [:one, "-", :two],
303
+ [:one, "+", :two]
304
+ )
305
+ end
306
+
307
+ parser = KPeg::Parser.new "1+2", gram
308
+ m = parser.parse
309
+
310
+ assert_equal 3, m.matches.size
311
+ assert_match m.matches[0], "1"
312
+ assert_match m.matches[1], "+"
313
+ assert_match m.matches[2], "2"
314
+
315
+ one = gram.find("one")
316
+ two = gram.find("two")
317
+
318
+ # We try 1 twice
319
+ assert_equal 2, parser.memoizations[one][0].uses
320
+
321
+ # but we only get as far as 2 once
322
+ assert_equal 1, parser.memoizations[two][2].uses
323
+ end
324
+
325
+ def test_left_recursion
326
+ gram = KPeg.grammar do |g|
327
+ g.num = g.reg(/[0-9]/)
328
+ g.expr = g.any [:expr, "-", :num], :num
329
+
330
+ g.root = g.expr
331
+ end
332
+
333
+ parser = KPeg::Parser.new "1-2-3", gram
334
+
335
+ m = parser.parse
336
+ assert_equal 3, m.matches.size
337
+
338
+ left = m.matches[0]
339
+ assert_equal 3, left.matches.size
340
+ assert_match left.matches[0], "1"
341
+ assert_match left.matches[1], "-"
342
+ assert_match left.matches[2], "2"
343
+ assert_match m.matches[1], "-"
344
+ assert_match m.matches[2], "3"
345
+
346
+ parser = KPeg::Parser.new "hello", gram
347
+ m = parser.parse
348
+
349
+ assert_equal nil, m
350
+ end
351
+
352
+ def test_math_grammar
353
+ gram = KPeg.grammar do |g|
354
+ g.num = '0'..'9'
355
+ g.term = g.seq(:term, "+", :term) \
356
+ | g.seq(:term, "-", :term) \
357
+ | :fact
358
+
359
+ g.fact = g.seq(:fact, "*", :fact) \
360
+ | g.seq(:fact, "/", :fact) \
361
+ | :num
362
+
363
+ g.root = g.term
364
+ end
365
+
366
+ sub = KPeg.match "4*3-8/9", gram
367
+ mul = sub.matches[0]
368
+ div = sub.matches[2]
369
+
370
+ assert_match mul.matches[0], "4"
371
+ assert_match mul.matches[1], "*"
372
+ assert_match mul.matches[2], "3"
373
+
374
+ assert_match sub.matches[1], "-"
375
+
376
+ assert_match div.matches[0], "8"
377
+ assert_match div.matches[1], "/"
378
+ assert_match div.matches[2], "9"
379
+ end
380
+
381
+ def test_calc
382
+ vars = {}
383
+ gram = KPeg.grammar do |g|
384
+ g.spaces = /\s*/
385
+ g.var = 'a'..'z'
386
+ g.num = g.lit(/[0-9]+/) { |i| i.to_i }
387
+
388
+ g.pri = g.seq(:spaces, :var) { |s,v| vars[v] } \
389
+ | g.seq(:spaces, :num) { |s,n| n } \
390
+ | g.seq('(', :expr, ')') { |_,e,_| e }
391
+
392
+ g.mul = g.seq(:mul, "*", :pri) { |x,_,y| x * y } \
393
+ | g.seq(:mul, "/", :pri) { |x,_,y| x / y } \
394
+ | :pri
395
+
396
+ g.add = g.seq(:add, "+", :mul) { |x,_,y| x + y } \
397
+ | g.seq(:add, "-", :mul) { |x,_,y| x - y } \
398
+ | :mul
399
+
400
+ g.expr = g.seq(:var, "=", :expr) { |v,_,e| vars[v] = e } \
401
+ | :add
402
+
403
+ g.root = g.seq(g.kleene(:expr), :spaces) { |e,_| e }
404
+ end
405
+
406
+ m = KPeg.match "3+4*5", gram
407
+ assert_equal 23, m.value
408
+
409
+ m = KPeg.match "x=2", gram
410
+ assert_equal 2, m.value
411
+
412
+ m = KPeg.match "x=x*7", gram
413
+ assert_equal 14, m.value
414
+ end
415
+
416
+ end
@@ -0,0 +1,1307 @@
1
+ require 'test/unit'
2
+ require 'kpeg'
3
+ require 'kpeg/code_generator'
4
+ require 'stringio'
5
+
6
+ class TestKPegCodeGenerator < Test::Unit::TestCase
7
+ def test_dot
8
+ gram = KPeg.grammar do |g|
9
+ g.root = g.dot
10
+ end
11
+
12
+ str = <<-STR
13
+ require 'kpeg/compiled_parser'
14
+
15
+ class Test < KPeg::CompiledParser
16
+
17
+ # root = .
18
+ def _root
19
+ _tmp = get_byte
20
+ set_failed_rule :_root unless _tmp
21
+ return _tmp
22
+ end
23
+
24
+ Rules = {}
25
+ Rules[:_root] = rule_info("root", ".")
26
+ end
27
+ STR
28
+
29
+ cg = KPeg::CodeGenerator.new "Test", gram
30
+
31
+ assert_equal str, cg.output
32
+
33
+ assert cg.parse("hello")
34
+ end
35
+
36
+ def test_str
37
+ gram = KPeg.grammar do |g|
38
+ g.root = g.str("hello")
39
+ end
40
+
41
+ str = <<-STR
42
+ require 'kpeg/compiled_parser'
43
+
44
+ class Test < KPeg::CompiledParser
45
+
46
+ # root = "hello"
47
+ def _root
48
+ _tmp = match_string("hello")
49
+ set_failed_rule :_root unless _tmp
50
+ return _tmp
51
+ end
52
+
53
+ Rules = {}
54
+ Rules[:_root] = rule_info("root", "\\\"hello\\\"")
55
+ end
56
+ STR
57
+
58
+ cg = KPeg::CodeGenerator.new "Test", gram
59
+
60
+ assert_equal str, cg.output
61
+
62
+ assert cg.parse("hello")
63
+ end
64
+
65
+ def test_reg
66
+ gram = KPeg.grammar do |g|
67
+ g.root = g.reg(/[0-9]/)
68
+ end
69
+
70
+ str = <<-STR
71
+ require 'kpeg/compiled_parser'
72
+
73
+ class Test < KPeg::CompiledParser
74
+
75
+ # root = /[0-9]/
76
+ def _root
77
+ _tmp = scan(/\\A(?-mix:[0-9])/)
78
+ set_failed_rule :_root unless _tmp
79
+ return _tmp
80
+ end
81
+
82
+ Rules = {}
83
+ Rules[:_root] = rule_info("root", "/[0-9]/")
84
+ end
85
+ STR
86
+
87
+ cg = KPeg::CodeGenerator.new "Test", gram
88
+
89
+ assert_equal str, cg.output
90
+
91
+ assert cg.parse("9")
92
+ assert cg.parse("1")
93
+ assert !cg.parse("a")
94
+ end
95
+
96
+ def test_char_range
97
+ gram = KPeg.grammar do |g|
98
+ g.root = g.range("a", "z")
99
+ end
100
+
101
+ str = <<-STR
102
+ require 'kpeg/compiled_parser'
103
+
104
+ class Test < KPeg::CompiledParser
105
+
106
+ # root = [a-z]
107
+ def _root
108
+ _save = self.pos
109
+ _tmp = get_byte
110
+ if _tmp
111
+ unless _tmp >= 97 and _tmp <= 122
112
+ self.pos = _save
113
+ _tmp = nil
114
+ end
115
+ end
116
+ set_failed_rule :_root unless _tmp
117
+ return _tmp
118
+ end
119
+
120
+ Rules = {}
121
+ Rules[:_root] = rule_info("root", "[a-z]")
122
+ end
123
+ STR
124
+
125
+ cg = KPeg::CodeGenerator.new "Test", gram
126
+
127
+ assert_equal str, cg.output
128
+
129
+ assert cg.parse("z")
130
+ assert cg.parse("a")
131
+ assert !cg.parse("0")
132
+ end
133
+
134
+ def test_char_range_in_seq
135
+ gram = KPeg.grammar do |g|
136
+ g.root = g.seq(g.range("a", "z"), "hello")
137
+ end
138
+
139
+ str = <<-STR
140
+ require 'kpeg/compiled_parser'
141
+
142
+ class Test < KPeg::CompiledParser
143
+
144
+ # root = [a-z] "hello"
145
+ def _root
146
+
147
+ _save = self.pos
148
+ while true # sequence
149
+ _save1 = self.pos
150
+ _tmp = get_byte
151
+ if _tmp
152
+ unless _tmp >= 97 and _tmp <= 122
153
+ self.pos = _save1
154
+ _tmp = nil
155
+ end
156
+ end
157
+ unless _tmp
158
+ self.pos = _save
159
+ break
160
+ end
161
+ _tmp = match_string("hello")
162
+ unless _tmp
163
+ self.pos = _save
164
+ end
165
+ break
166
+ end # end sequence
167
+
168
+ set_failed_rule :_root unless _tmp
169
+ return _tmp
170
+ end
171
+
172
+ Rules = {}
173
+ Rules[:_root] = rule_info("root", "[a-z] \\\"hello\\\"")
174
+ end
175
+ STR
176
+
177
+ cg = KPeg::CodeGenerator.new "Test", gram
178
+
179
+ assert_equal str, cg.output
180
+
181
+ assert cg.parse("ahello")
182
+ assert cg.parse("zhello")
183
+ assert !cg.parse("0hello")
184
+ assert !cg.parse("ajello")
185
+ end
186
+
187
+ def test_any
188
+ gram = KPeg.grammar do |g|
189
+ g.root = g.any("hello", "world")
190
+ end
191
+
192
+ str = <<-STR
193
+ require 'kpeg/compiled_parser'
194
+
195
+ class Test < KPeg::CompiledParser
196
+
197
+ # root = ("hello" | "world")
198
+ def _root
199
+
200
+ _save = self.pos
201
+ while true # choice
202
+ _tmp = match_string("hello")
203
+ break if _tmp
204
+ self.pos = _save
205
+ _tmp = match_string("world")
206
+ break if _tmp
207
+ self.pos = _save
208
+ break
209
+ end # end choice
210
+
211
+ set_failed_rule :_root unless _tmp
212
+ return _tmp
213
+ end
214
+
215
+ Rules = {}
216
+ Rules[:_root] = rule_info("root", "(\\\"hello\\\" | \\\"world\\\")")
217
+ end
218
+ STR
219
+
220
+ cg = KPeg::CodeGenerator.new "Test", gram
221
+
222
+ assert_equal str, cg.output
223
+
224
+ assert cg.parse("hello")
225
+ assert cg.parse("world")
226
+ assert !cg.parse("jello")
227
+ end
228
+
229
+ def test_any_resets_pos
230
+ gram = KPeg.grammar do |g|
231
+ g.root = g.any(g.seq("hello", "world"), "hello balloons")
232
+ end
233
+
234
+ cg = KPeg::CodeGenerator.new "Test", gram
235
+
236
+ code = cg.make("helloworld")
237
+ assert code.parse
238
+ assert_equal 10, code.pos
239
+
240
+ assert cg.parse("hello balloons")
241
+ end
242
+
243
+ def test_maybe
244
+ gram = KPeg.grammar do |g|
245
+ g.root = g.maybe("hello")
246
+ end
247
+
248
+ str = <<-STR
249
+ require 'kpeg/compiled_parser'
250
+
251
+ class Test < KPeg::CompiledParser
252
+
253
+ # root = "hello"?
254
+ def _root
255
+ _save = self.pos
256
+ _tmp = match_string("hello")
257
+ unless _tmp
258
+ _tmp = true
259
+ self.pos = _save
260
+ end
261
+ set_failed_rule :_root unless _tmp
262
+ return _tmp
263
+ end
264
+
265
+ Rules = {}
266
+ Rules[:_root] = rule_info("root", "\\\"hello\\\"?")
267
+ end
268
+ STR
269
+
270
+ cg = KPeg::CodeGenerator.new "Test", gram
271
+
272
+ assert_equal str, cg.output
273
+
274
+ assert cg.parse("hello")
275
+ assert cg.parse("jello")
276
+ end
277
+
278
+ def test_maybe_resets_pos
279
+ gram = KPeg.grammar do |g|
280
+ g.root = g.maybe(g.seq("hello", "world"))
281
+ end
282
+
283
+ cg = KPeg::CodeGenerator.new "Test", gram
284
+
285
+ assert cg.parse("helloworld")
286
+
287
+ code = cg.make("hellojello")
288
+ assert code.parse
289
+ assert_equal 0, code.pos
290
+ end
291
+
292
+ def test_kleene
293
+ gram = KPeg.grammar do |g|
294
+ g.root = g.kleene("hello")
295
+ end
296
+
297
+ str = <<-STR
298
+ require 'kpeg/compiled_parser'
299
+
300
+ class Test < KPeg::CompiledParser
301
+
302
+ # root = "hello"*
303
+ def _root
304
+ while true
305
+ _tmp = match_string("hello")
306
+ break unless _tmp
307
+ end
308
+ _tmp = true
309
+ set_failed_rule :_root unless _tmp
310
+ return _tmp
311
+ end
312
+
313
+ Rules = {}
314
+ Rules[:_root] = rule_info("root", "\\\"hello\\\"*")
315
+ end
316
+ STR
317
+
318
+ cg = KPeg::CodeGenerator.new "Test", gram
319
+
320
+ assert_equal str, cg.output
321
+
322
+ code = cg.make("hellohellohello")
323
+ assert code.parse
324
+ assert_equal 15, code.pos
325
+ end
326
+
327
+ def test_kleene_reset_pos
328
+ gram = KPeg.grammar do |g|
329
+ g.root = g.kleene(g.seq("hello", "world"))
330
+ end
331
+
332
+ cg = KPeg::CodeGenerator.new "Test", gram
333
+
334
+ code = cg.make("helloworldhelloworld")
335
+ assert code.parse
336
+ assert_equal 20, code.pos
337
+
338
+ code = cg.make("hellojello")
339
+ assert code.parse
340
+ assert_equal 0, code.pos
341
+ end
342
+
343
+ def test_many
344
+ gram = KPeg.grammar do |g|
345
+ g.root = g.many("hello")
346
+ end
347
+
348
+ str = <<-STR
349
+ require 'kpeg/compiled_parser'
350
+
351
+ class Test < KPeg::CompiledParser
352
+
353
+ # root = "hello"+
354
+ def _root
355
+ _save = self.pos
356
+ _tmp = match_string("hello")
357
+ if _tmp
358
+ while true
359
+ _tmp = match_string("hello")
360
+ break unless _tmp
361
+ end
362
+ _tmp = true
363
+ else
364
+ self.pos = _save
365
+ end
366
+ set_failed_rule :_root unless _tmp
367
+ return _tmp
368
+ end
369
+
370
+ Rules = {}
371
+ Rules[:_root] = rule_info("root", "\\\"hello\\\"+")
372
+ end
373
+ STR
374
+
375
+ cg = KPeg::CodeGenerator.new "Test", gram
376
+
377
+ assert_equal str, cg.output
378
+
379
+ code = cg.make("hellohello")
380
+ assert code.parse
381
+ assert_equal 10, code.pos
382
+
383
+ code = cg.make("hello")
384
+ assert code.parse
385
+ assert_equal 5, code.pos
386
+
387
+ code = cg.make("")
388
+ assert !code.parse
389
+ end
390
+
391
+ def test_many_resets_pos
392
+ gram = KPeg.grammar do |g|
393
+ g.root = g.many(g.seq("hello", "world"))
394
+ end
395
+
396
+ cg = KPeg::CodeGenerator.new "Test", gram
397
+
398
+ code = cg.make("helloworldhelloworld")
399
+ assert code.parse
400
+ assert_equal 20, code.pos
401
+
402
+ code = cg.make("hellojello")
403
+ assert !code.parse
404
+ assert_equal 0, code.pos
405
+ end
406
+
407
+ def test_multiple
408
+ gram = KPeg.grammar do |g|
409
+ g.root = g.multiple("hello", 5, 9)
410
+ end
411
+
412
+ str = <<-STR
413
+ require 'kpeg/compiled_parser'
414
+
415
+ class Test < KPeg::CompiledParser
416
+
417
+ # root = "hello"[5, 9]
418
+ def _root
419
+ _save = self.pos
420
+ _count = 0
421
+ while true
422
+ _tmp = match_string("hello")
423
+ if _tmp
424
+ _count += 1
425
+ break if _count == 9
426
+ else
427
+ break
428
+ end
429
+ end
430
+ if _count >= 5
431
+ _tmp = true
432
+ else
433
+ self.pos = _save
434
+ _tmp = nil
435
+ end
436
+ set_failed_rule :_root unless _tmp
437
+ return _tmp
438
+ end
439
+
440
+ Rules = {}
441
+ Rules[:_root] = rule_info("root", "\\\"hello\\\"[5, 9]")
442
+ end
443
+ STR
444
+
445
+ cg = KPeg::CodeGenerator.new "Test", gram
446
+
447
+ assert_equal str, cg.output
448
+ end
449
+
450
+ def test_seq
451
+ gram = KPeg.grammar do |g|
452
+ g.root = g.seq("hello", "world")
453
+ end
454
+
455
+ str = <<-STR
456
+ require 'kpeg/compiled_parser'
457
+
458
+ class Test < KPeg::CompiledParser
459
+
460
+ # root = "hello" "world"
461
+ def _root
462
+
463
+ _save = self.pos
464
+ while true # sequence
465
+ _tmp = match_string("hello")
466
+ unless _tmp
467
+ self.pos = _save
468
+ break
469
+ end
470
+ _tmp = match_string("world")
471
+ unless _tmp
472
+ self.pos = _save
473
+ end
474
+ break
475
+ end # end sequence
476
+
477
+ set_failed_rule :_root unless _tmp
478
+ return _tmp
479
+ end
480
+
481
+ Rules = {}
482
+ Rules[:_root] = rule_info("root", "\\\"hello\\\" \\\"world\\\"")
483
+ end
484
+ STR
485
+
486
+ cg = KPeg::CodeGenerator.new "Test", gram
487
+
488
+ assert_equal str, cg.output
489
+ end
490
+
491
+ def test_seq_resets_pos
492
+ gram = KPeg.grammar do |g|
493
+ g.root = g.seq("hello", "world")
494
+ end
495
+
496
+ cg = KPeg::CodeGenerator.new "Test", gram
497
+
498
+ code = cg.make("helloworld")
499
+ assert code.parse
500
+
501
+ code = cg.make("hellojello")
502
+ assert !code.parse
503
+ assert_equal 0, code.pos
504
+ end
505
+
506
+ def test_andp
507
+ gram = KPeg.grammar do |g|
508
+ g.root = g.andp("hello")
509
+ end
510
+
511
+ str = <<-STR
512
+ require 'kpeg/compiled_parser'
513
+
514
+ class Test < KPeg::CompiledParser
515
+
516
+ # root = &"hello"
517
+ def _root
518
+ _save = self.pos
519
+ _tmp = match_string("hello")
520
+ self.pos = _save
521
+ set_failed_rule :_root unless _tmp
522
+ return _tmp
523
+ end
524
+
525
+ Rules = {}
526
+ Rules[:_root] = rule_info("root", "&\\\"hello\\\"")
527
+ end
528
+ STR
529
+
530
+ cg = KPeg::CodeGenerator.new "Test", gram
531
+
532
+ assert_equal str, cg.output
533
+
534
+ code = cg.make("hello")
535
+ assert code.parse
536
+ assert_equal 0, code.pos
537
+
538
+ code = cg.make("jello")
539
+ assert !code.parse
540
+ assert_equal 0, code.pos
541
+ end
542
+
543
+ def test_andp_for_action
544
+ gram = KPeg.grammar do |g|
545
+ g.root = g.andp(g.action(" !defined? @fail "))
546
+ end
547
+
548
+ str = <<-STR
549
+ require 'kpeg/compiled_parser'
550
+
551
+ class Test < KPeg::CompiledParser
552
+
553
+ # root = &{ !defined? @fail }
554
+ def _root
555
+ _save = self.pos
556
+ _tmp = begin; !defined? @fail ; end
557
+ self.pos = _save
558
+ set_failed_rule :_root unless _tmp
559
+ return _tmp
560
+ end
561
+
562
+ Rules = {}
563
+ Rules[:_root] = rule_info("root", "&{ !defined? @fail }")
564
+ end
565
+ STR
566
+
567
+ cg = KPeg::CodeGenerator.new "Test", gram
568
+
569
+ assert_equal str, cg.output
570
+
571
+ code = cg.make("hello")
572
+ assert code.parse
573
+ assert_equal 0, code.pos
574
+
575
+ code = cg.make("jello")
576
+ code.instance_variable_set :@fail, true
577
+ assert !code.parse
578
+ assert_equal 0, code.pos
579
+ end
580
+
581
+ def test_notp
582
+ gram = KPeg.grammar do |g|
583
+ g.root = g.notp("hello")
584
+ end
585
+
586
+ str = <<-STR
587
+ require 'kpeg/compiled_parser'
588
+
589
+ class Test < KPeg::CompiledParser
590
+
591
+ # root = !"hello"
592
+ def _root
593
+ _save = self.pos
594
+ _tmp = match_string("hello")
595
+ _tmp = _tmp ? nil : true
596
+ self.pos = _save
597
+ set_failed_rule :_root unless _tmp
598
+ return _tmp
599
+ end
600
+
601
+ Rules = {}
602
+ Rules[:_root] = rule_info("root", "!\\\"hello\\\"")
603
+ end
604
+ STR
605
+
606
+ cg = KPeg::CodeGenerator.new "Test", gram
607
+
608
+ assert_equal str, cg.output
609
+
610
+ code = cg.make("hello")
611
+ assert !code.parse
612
+ assert_equal 0, code.pos
613
+
614
+ code = cg.make("jello")
615
+ assert code.parse
616
+ assert_equal 0, code.pos
617
+ end
618
+
619
+ def test_notp_for_action
620
+ gram = KPeg.grammar do |g|
621
+ g.root = g.notp(g.action(" defined? @fail "))
622
+ end
623
+
624
+ str = <<-STR
625
+ require 'kpeg/compiled_parser'
626
+
627
+ class Test < KPeg::CompiledParser
628
+
629
+ # root = !{ defined? @fail }
630
+ def _root
631
+ _save = self.pos
632
+ _tmp = begin; defined? @fail ; end
633
+ _tmp = _tmp ? nil : true
634
+ self.pos = _save
635
+ set_failed_rule :_root unless _tmp
636
+ return _tmp
637
+ end
638
+
639
+ Rules = {}
640
+ Rules[:_root] = rule_info("root", "!{ defined? @fail }")
641
+ end
642
+ STR
643
+
644
+ cg = KPeg::CodeGenerator.new "Test", gram
645
+
646
+ assert_equal str, cg.output
647
+
648
+ code = cg.make("hello")
649
+ assert code.parse
650
+ assert_equal 0, code.pos
651
+
652
+ code = cg.make("jello")
653
+ code.instance_variable_set :@fail, true
654
+ assert !code.parse
655
+ assert_equal 0, code.pos
656
+ end
657
+
658
+
659
+ def test_ref
660
+ gram = KPeg.grammar do |g|
661
+ g.greeting = "hello"
662
+ g.root = g.ref("greeting")
663
+ end
664
+
665
+ str = <<-STR
666
+ require 'kpeg/compiled_parser'
667
+
668
+ class Test < KPeg::CompiledParser
669
+
670
+ # greeting = "hello"
671
+ def _greeting
672
+ _tmp = match_string("hello")
673
+ set_failed_rule :_greeting unless _tmp
674
+ return _tmp
675
+ end
676
+
677
+ # root = greeting
678
+ def _root
679
+ _tmp = apply(:_greeting)
680
+ set_failed_rule :_root unless _tmp
681
+ return _tmp
682
+ end
683
+
684
+ Rules = {}
685
+ Rules[:_greeting] = rule_info("greeting", "\\\"hello\\\"")
686
+ Rules[:_root] = rule_info("root", "greeting")
687
+ end
688
+ STR
689
+
690
+ cg = KPeg::CodeGenerator.new "Test", gram
691
+
692
+ assert_equal str, cg.output
693
+
694
+ assert cg.parse("hello")
695
+ end
696
+
697
+ def test_invoke
698
+ gram = KPeg.grammar do |g|
699
+ g.greeting = "hello"
700
+ g.root = g.invoke("greeting")
701
+ end
702
+
703
+ str = <<-STR
704
+ require 'kpeg/compiled_parser'
705
+
706
+ class Test < KPeg::CompiledParser
707
+
708
+ # greeting = "hello"
709
+ def _greeting
710
+ _tmp = match_string("hello")
711
+ set_failed_rule :_greeting unless _tmp
712
+ return _tmp
713
+ end
714
+
715
+ # root = @greeting
716
+ def _root
717
+ _tmp = _greeting()
718
+ set_failed_rule :_root unless _tmp
719
+ return _tmp
720
+ end
721
+
722
+ Rules = {}
723
+ Rules[:_greeting] = rule_info("greeting", "\\\"hello\\\"")
724
+ Rules[:_root] = rule_info("root", "@greeting")
725
+ end
726
+ STR
727
+
728
+ cg = KPeg::CodeGenerator.new "Test", gram
729
+
730
+ assert_equal str, cg.output
731
+
732
+ assert cg.parse("hello")
733
+ end
734
+
735
+ def test_invoke_with_args
736
+ gram = KPeg.grammar do |g|
737
+ g.set("greeting", "hello", ["a", "b"])
738
+ g.root = g.invoke("greeting", "(1,2)")
739
+ end
740
+
741
+ str = <<-STR
742
+ require 'kpeg/compiled_parser'
743
+
744
+ class Test < KPeg::CompiledParser
745
+
746
+ # greeting = "hello"
747
+ def _greeting(a,b)
748
+ _tmp = match_string("hello")
749
+ set_failed_rule :_greeting unless _tmp
750
+ return _tmp
751
+ end
752
+
753
+ # root = greeting(1,2)
754
+ def _root
755
+ _tmp = _greeting(1,2)
756
+ set_failed_rule :_root unless _tmp
757
+ return _tmp
758
+ end
759
+
760
+ Rules = {}
761
+ Rules[:_greeting] = rule_info("greeting", "\\\"hello\\\"")
762
+ Rules[:_root] = rule_info("root", "greeting(1,2)")
763
+ end
764
+ STR
765
+
766
+ cg = KPeg::CodeGenerator.new "Test", gram
767
+
768
+ assert_equal str, cg.output
769
+
770
+ assert cg.parse("hello")
771
+ end
772
+
773
+ gram = <<-GRAM
774
+ greeting = "hello"
775
+ greeting2(a,b) = "hello"
776
+ GRAM
777
+
778
+ KPeg.compile gram, "TestParser", self
779
+
780
+ def test_foreign_invoke
781
+ gram = KPeg.grammar do |g|
782
+ g.add_foreign_grammar "blah", "TestKPegCodeGenerator::TestParser"
783
+ g.root = g.foreign_invoke("blah", "greeting")
784
+ end
785
+
786
+ str = <<-STR
787
+ require 'kpeg/compiled_parser'
788
+
789
+ class Test < KPeg::CompiledParser
790
+ def setup_foreign_grammar
791
+ @_grammar_blah = TestKPegCodeGenerator::TestParser.new(nil)
792
+ end
793
+
794
+ # root = %blah.greeting
795
+ def _root
796
+ _tmp = @_grammar_blah.external_invoke(self, :_greeting)
797
+ set_failed_rule :_root unless _tmp
798
+ return _tmp
799
+ end
800
+
801
+ Rules = {}
802
+ Rules[:_root] = rule_info("root", "%blah.greeting")
803
+ end
804
+ STR
805
+
806
+ cg = KPeg::CodeGenerator.new "Test", gram
807
+
808
+ assert_equal str, cg.output
809
+
810
+ assert cg.parse("hello")
811
+ end
812
+
813
+ def test_foreign_invoke_with_args
814
+ gram = KPeg.grammar do |g|
815
+ g.add_foreign_grammar "blah", "TestKPegCodeGenerator::TestParser"
816
+ g.root = g.foreign_invoke("blah", "greeting2", "(1,2)")
817
+ end
818
+
819
+ str = <<-STR
820
+ require 'kpeg/compiled_parser'
821
+
822
+ class Test < KPeg::CompiledParser
823
+ def setup_foreign_grammar
824
+ @_grammar_blah = TestKPegCodeGenerator::TestParser.new(nil)
825
+ end
826
+
827
+ # root = %blah.greeting2(1,2)
828
+ def _root
829
+ _tmp = @_grammar_blah.external_invoke(self, :_greeting2, 1,2)
830
+ set_failed_rule :_root unless _tmp
831
+ return _tmp
832
+ end
833
+
834
+ Rules = {}
835
+ Rules[:_root] = rule_info("root", "%blah.greeting2(1,2)")
836
+ end
837
+ STR
838
+
839
+ cg = KPeg::CodeGenerator.new "Test", gram
840
+
841
+ assert_equal str, cg.output
842
+
843
+ assert cg.parse("hello")
844
+ end
845
+
846
+ def test_tag
847
+ gram = KPeg.grammar do |g|
848
+ g.root = g.t g.str("hello"), "t"
849
+ end
850
+
851
+ str = <<-STR
852
+ require 'kpeg/compiled_parser'
853
+
854
+ class Test < KPeg::CompiledParser
855
+
856
+ # root = "hello":t
857
+ def _root
858
+ _tmp = match_string("hello")
859
+ t = @result
860
+ set_failed_rule :_root unless _tmp
861
+ return _tmp
862
+ end
863
+
864
+ Rules = {}
865
+ Rules[:_root] = rule_info("root", "\\\"hello\\\":t")
866
+ end
867
+ STR
868
+
869
+ cg = KPeg::CodeGenerator.new "Test", gram
870
+
871
+ assert_equal str, cg.output
872
+ end
873
+
874
+ def test_noname_tag
875
+ gram = KPeg.grammar do |g|
876
+ g.root = g.t g.str("hello")
877
+ end
878
+
879
+ str = <<-STR
880
+ require 'kpeg/compiled_parser'
881
+
882
+ class Test < KPeg::CompiledParser
883
+
884
+ # root = "hello"
885
+ def _root
886
+ _tmp = match_string("hello")
887
+ set_failed_rule :_root unless _tmp
888
+ return _tmp
889
+ end
890
+
891
+ Rules = {}
892
+ Rules[:_root] = rule_info("root", "\\\"hello\\\"")
893
+ end
894
+ STR
895
+
896
+ cg = KPeg::CodeGenerator.new "Test", gram
897
+
898
+ assert_equal str, cg.output
899
+ end
900
+
901
+ def test_tag_maybe
902
+ gram = KPeg.grammar do |g|
903
+ g.hello = g.seq(g.collect("hello"), g.action("text"))
904
+ g.root = g.seq g.t(g.maybe(:hello), "lots"), g.action("lots")
905
+ end
906
+
907
+ str = <<-STR
908
+ require 'kpeg/compiled_parser'
909
+
910
+ class Test < KPeg::CompiledParser
911
+
912
+ # hello = < "hello" > {text}
913
+ def _hello
914
+
915
+ _save = self.pos
916
+ while true # sequence
917
+ _text_start = self.pos
918
+ _tmp = match_string("hello")
919
+ if _tmp
920
+ text = get_text(_text_start)
921
+ end
922
+ unless _tmp
923
+ self.pos = _save
924
+ break
925
+ end
926
+ @result = begin; text; end
927
+ _tmp = true
928
+ unless _tmp
929
+ self.pos = _save
930
+ end
931
+ break
932
+ end # end sequence
933
+
934
+ set_failed_rule :_hello unless _tmp
935
+ return _tmp
936
+ end
937
+
938
+ # root = hello?:lots {lots}
939
+ def _root
940
+
941
+ _save = self.pos
942
+ while true # sequence
943
+ _save1 = self.pos
944
+ _tmp = apply(:_hello)
945
+ @result = nil unless _tmp
946
+ unless _tmp
947
+ _tmp = true
948
+ self.pos = _save1
949
+ end
950
+ lots = @result
951
+ unless _tmp
952
+ self.pos = _save
953
+ break
954
+ end
955
+ @result = begin; lots; end
956
+ _tmp = true
957
+ unless _tmp
958
+ self.pos = _save
959
+ end
960
+ break
961
+ end # end sequence
962
+
963
+ set_failed_rule :_root unless _tmp
964
+ return _tmp
965
+ end
966
+
967
+ Rules = {}
968
+ Rules[:_hello] = rule_info("hello", "< \\\"hello\\\" > {text}")
969
+ Rules[:_root] = rule_info("root", "hello?:lots {lots}")
970
+ end
971
+ STR
972
+
973
+ cg = KPeg::CodeGenerator.new "Test", gram
974
+
975
+ assert_equal str, cg.output
976
+
977
+ code = cg.make("hello")
978
+ assert code.parse
979
+ assert_equal "hello", code.result
980
+
981
+ code = cg.make("")
982
+ assert code.parse
983
+ assert_equal nil, code.result
984
+ end
985
+
986
+
987
+ def test_tag_multiple
988
+ gram = KPeg.grammar do |g|
989
+ g.hello = g.seq(g.collect("hello"), g.action("text"))
990
+ g.root = g.seq g.t(g.kleene(:hello), "lots"), g.action("lots")
991
+ end
992
+
993
+ str = <<-STR
994
+ require 'kpeg/compiled_parser'
995
+
996
+ class Test < KPeg::CompiledParser
997
+
998
+ # hello = < "hello" > {text}
999
+ def _hello
1000
+
1001
+ _save = self.pos
1002
+ while true # sequence
1003
+ _text_start = self.pos
1004
+ _tmp = match_string("hello")
1005
+ if _tmp
1006
+ text = get_text(_text_start)
1007
+ end
1008
+ unless _tmp
1009
+ self.pos = _save
1010
+ break
1011
+ end
1012
+ @result = begin; text; end
1013
+ _tmp = true
1014
+ unless _tmp
1015
+ self.pos = _save
1016
+ end
1017
+ break
1018
+ end # end sequence
1019
+
1020
+ set_failed_rule :_hello unless _tmp
1021
+ return _tmp
1022
+ end
1023
+
1024
+ # root = hello*:lots {lots}
1025
+ def _root
1026
+
1027
+ _save = self.pos
1028
+ while true # sequence
1029
+ _ary = []
1030
+ while true
1031
+ _tmp = apply(:_hello)
1032
+ _ary << @result if _tmp
1033
+ break unless _tmp
1034
+ end
1035
+ _tmp = true
1036
+ @result = _ary
1037
+ lots = @result
1038
+ unless _tmp
1039
+ self.pos = _save
1040
+ break
1041
+ end
1042
+ @result = begin; lots; end
1043
+ _tmp = true
1044
+ unless _tmp
1045
+ self.pos = _save
1046
+ end
1047
+ break
1048
+ end # end sequence
1049
+
1050
+ set_failed_rule :_root unless _tmp
1051
+ return _tmp
1052
+ end
1053
+
1054
+ Rules = {}
1055
+ Rules[:_hello] = rule_info("hello", "< \\\"hello\\\" > {text}")
1056
+ Rules[:_root] = rule_info("root", "hello*:lots {lots}")
1057
+ end
1058
+ STR
1059
+
1060
+ cg = KPeg::CodeGenerator.new "Test", gram
1061
+
1062
+ assert_equal str, cg.output
1063
+
1064
+ code = cg.make("hellohello")
1065
+ assert code.parse
1066
+ assert_equal ["hello", "hello"], code.result
1067
+
1068
+ code = cg.make("hello")
1069
+ assert code.parse
1070
+ assert_equal ["hello"], code.result
1071
+
1072
+ code = cg.make("")
1073
+ assert code.parse
1074
+ assert_equal [], code.result
1075
+ end
1076
+
1077
+ def test_tag_many
1078
+ gram = KPeg.grammar do |g|
1079
+ g.hello = g.seq(g.collect("hello"), g.action("text"))
1080
+ g.root = g.seq g.t(g.many(:hello), "lots"), g.action("lots")
1081
+ end
1082
+
1083
+ str = <<-STR
1084
+ require 'kpeg/compiled_parser'
1085
+
1086
+ class Test < KPeg::CompiledParser
1087
+
1088
+ # hello = < "hello" > {text}
1089
+ def _hello
1090
+
1091
+ _save = self.pos
1092
+ while true # sequence
1093
+ _text_start = self.pos
1094
+ _tmp = match_string("hello")
1095
+ if _tmp
1096
+ text = get_text(_text_start)
1097
+ end
1098
+ unless _tmp
1099
+ self.pos = _save
1100
+ break
1101
+ end
1102
+ @result = begin; text; end
1103
+ _tmp = true
1104
+ unless _tmp
1105
+ self.pos = _save
1106
+ end
1107
+ break
1108
+ end # end sequence
1109
+
1110
+ set_failed_rule :_hello unless _tmp
1111
+ return _tmp
1112
+ end
1113
+
1114
+ # root = hello+:lots {lots}
1115
+ def _root
1116
+
1117
+ _save = self.pos
1118
+ while true # sequence
1119
+ _save1 = self.pos
1120
+ _ary = []
1121
+ _tmp = apply(:_hello)
1122
+ if _tmp
1123
+ _ary << @result
1124
+ while true
1125
+ _tmp = apply(:_hello)
1126
+ _ary << @result if _tmp
1127
+ break unless _tmp
1128
+ end
1129
+ _tmp = true
1130
+ @result = _ary
1131
+ else
1132
+ self.pos = _save1
1133
+ end
1134
+ lots = @result
1135
+ unless _tmp
1136
+ self.pos = _save
1137
+ break
1138
+ end
1139
+ @result = begin; lots; end
1140
+ _tmp = true
1141
+ unless _tmp
1142
+ self.pos = _save
1143
+ end
1144
+ break
1145
+ end # end sequence
1146
+
1147
+ set_failed_rule :_root unless _tmp
1148
+ return _tmp
1149
+ end
1150
+
1151
+ Rules = {}
1152
+ Rules[:_hello] = rule_info("hello", "< \\\"hello\\\" > {text}")
1153
+ Rules[:_root] = rule_info("root", "hello+:lots {lots}")
1154
+ end
1155
+ STR
1156
+
1157
+ cg = KPeg::CodeGenerator.new "Test", gram
1158
+
1159
+ assert_equal str, cg.output
1160
+
1161
+ code = cg.make("hellohello")
1162
+ assert code.parse
1163
+ assert_equal ["hello", "hello"], code.result
1164
+
1165
+ code = cg.make("hello")
1166
+ assert code.parse
1167
+ assert_equal ["hello"], code.result
1168
+
1169
+ code = cg.make("")
1170
+ assert !code.parse
1171
+ end
1172
+
1173
+ def test_action
1174
+ gram = KPeg.grammar do |g|
1175
+ g.root = g.action "3 + 4"
1176
+ end
1177
+
1178
+ str = <<-STR
1179
+ require 'kpeg/compiled_parser'
1180
+
1181
+ class Test < KPeg::CompiledParser
1182
+
1183
+ # root = {3 + 4}
1184
+ def _root
1185
+ @result = begin; 3 + 4; end
1186
+ _tmp = true
1187
+ set_failed_rule :_root unless _tmp
1188
+ return _tmp
1189
+ end
1190
+
1191
+ Rules = {}
1192
+ Rules[:_root] = rule_info("root", "{3 + 4}")
1193
+ end
1194
+ STR
1195
+
1196
+ cg = KPeg::CodeGenerator.new "Test", gram
1197
+
1198
+ assert_equal str, cg.output
1199
+
1200
+ code = cg.make("")
1201
+ assert code.parse
1202
+ assert_equal 7, code.result
1203
+ end
1204
+
1205
+ def test_collect
1206
+ gram = KPeg.grammar do |g|
1207
+ g.root = g.seq(g.collect("hello"), g.action(" text "))
1208
+ end
1209
+
1210
+ str = <<-STR
1211
+ require 'kpeg/compiled_parser'
1212
+
1213
+ class Test < KPeg::CompiledParser
1214
+
1215
+ # root = < "hello" > { text }
1216
+ def _root
1217
+
1218
+ _save = self.pos
1219
+ while true # sequence
1220
+ _text_start = self.pos
1221
+ _tmp = match_string("hello")
1222
+ if _tmp
1223
+ text = get_text(_text_start)
1224
+ end
1225
+ unless _tmp
1226
+ self.pos = _save
1227
+ break
1228
+ end
1229
+ @result = begin; text ; end
1230
+ _tmp = true
1231
+ unless _tmp
1232
+ self.pos = _save
1233
+ end
1234
+ break
1235
+ end # end sequence
1236
+
1237
+ set_failed_rule :_root unless _tmp
1238
+ return _tmp
1239
+ end
1240
+
1241
+ Rules = {}
1242
+ Rules[:_root] = rule_info("root", "< \\\"hello\\\" > { text }")
1243
+ end
1244
+ STR
1245
+
1246
+ cg = KPeg::CodeGenerator.new "Test", gram
1247
+
1248
+ assert_equal str, cg.output
1249
+
1250
+ code = cg.make("hello")
1251
+ assert code.parse
1252
+ assert_equal "hello", code.result
1253
+ end
1254
+
1255
+ def test_parse_error
1256
+ gram = KPeg.grammar do |g|
1257
+ g.world = "world"
1258
+ g.root = g.seq("hello", :world)
1259
+ end
1260
+
1261
+ cg = KPeg::CodeGenerator.new "Test", gram
1262
+
1263
+ code = cg.make("no")
1264
+ assert !code.parse
1265
+ assert_equal 0, code.failing_rule_offset
1266
+
1267
+ cg2 = KPeg::CodeGenerator.new "Test", gram
1268
+
1269
+ code = cg2.make("hellono")
1270
+ assert !code.parse
1271
+ assert_equal 5, code.failing_rule_offset
1272
+ end
1273
+
1274
+ def test_setup_actions
1275
+ gram = KPeg.grammar do |g|
1276
+ g.root = g.dot
1277
+ g.add_setup g.action(" attr_reader :foo ")
1278
+ end
1279
+
1280
+ str = <<-STR
1281
+ require 'kpeg/compiled_parser'
1282
+
1283
+ class Test < KPeg::CompiledParser
1284
+
1285
+ attr_reader :foo
1286
+
1287
+
1288
+ # root = .
1289
+ def _root
1290
+ _tmp = get_byte
1291
+ set_failed_rule :_root unless _tmp
1292
+ return _tmp
1293
+ end
1294
+
1295
+ Rules = {}
1296
+ Rules[:_root] = rule_info("root", ".")
1297
+ end
1298
+ STR
1299
+
1300
+ cg = KPeg::CodeGenerator.new "Test", gram
1301
+
1302
+ assert_equal str, cg.output
1303
+
1304
+ assert cg.parse("hello")
1305
+ end
1306
+
1307
+ end