kpeg 0.7

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,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