yaparc 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/yaparc.rb +11 -280
- data/tests/test_parser.rb +9 -8
- metadata +2 -2
data/lib/yaparc.rb
CHANGED
@@ -30,14 +30,6 @@ module Yaparc
|
|
30
30
|
end
|
31
31
|
result
|
32
32
|
end
|
33
|
-
# def parse(input, &block)
|
34
|
-
# result = @parser.call(input)
|
35
|
-
# if block_given?
|
36
|
-
# @tree = yield result
|
37
|
-
# else
|
38
|
-
# @tree = result
|
39
|
-
# end
|
40
|
-
# end
|
41
33
|
|
42
34
|
def eval
|
43
35
|
tree = parse(input)
|
@@ -103,16 +95,6 @@ module Yaparc
|
|
103
95
|
@remaining = remaining
|
104
96
|
end
|
105
97
|
end
|
106
|
-
# class SucceedParser
|
107
|
-
# include Parsable
|
108
|
-
# attr_reader :remaining
|
109
|
-
# def initialize(value, remaining = nil)
|
110
|
-
# @parser = lambda do |input|
|
111
|
-
# [[value, input]]
|
112
|
-
# end
|
113
|
-
# @remaining = remaining
|
114
|
-
# end
|
115
|
-
# end
|
116
98
|
|
117
99
|
class FailParser
|
118
100
|
include Parsable
|
@@ -123,14 +105,6 @@ module Yaparc
|
|
123
105
|
end
|
124
106
|
end
|
125
107
|
|
126
|
-
# class FailParser
|
127
|
-
# include Parsable
|
128
|
-
# def initialize
|
129
|
-
# @parser = lambda do |input|
|
130
|
-
# []
|
131
|
-
# end
|
132
|
-
# end
|
133
|
-
# end
|
134
108
|
|
135
109
|
class ItemParser
|
136
110
|
include Parsable
|
@@ -146,19 +120,6 @@ module Yaparc
|
|
146
120
|
end
|
147
121
|
end
|
148
122
|
|
149
|
-
# class ItemParser
|
150
|
-
# include Parsable
|
151
|
-
# def initialize
|
152
|
-
# @parser = lambda do |input|
|
153
|
-
# if input.nil? or input.empty?
|
154
|
-
# []
|
155
|
-
# else
|
156
|
-
# [[input[0..0],input[1..input.length]]]
|
157
|
-
# end
|
158
|
-
# end
|
159
|
-
# end
|
160
|
-
# end
|
161
|
-
|
162
123
|
class SatisfyParser
|
163
124
|
include Parsable
|
164
125
|
def initialize(predicate)
|
@@ -190,37 +151,6 @@ module Yaparc
|
|
190
151
|
end
|
191
152
|
end
|
192
153
|
|
193
|
-
# class SatisfyParser
|
194
|
-
# include Parsable
|
195
|
-
# def initialize(predicate)
|
196
|
-
# assert_at(__FILE__,__LINE__){predicate.instance_of?(Proc)}
|
197
|
-
|
198
|
-
# @parser = lambda do |input|
|
199
|
-
# item = ItemParser.new.parse(input)
|
200
|
-
# if item == []
|
201
|
-
# FailParser.new
|
202
|
-
# else
|
203
|
-
# parser = if predicate.call(item[0][0])
|
204
|
-
# SucceedParser.new(item[0][0], item[0][1])
|
205
|
-
# else
|
206
|
-
# FailParser.new
|
207
|
-
# end
|
208
|
-
# end
|
209
|
-
# end
|
210
|
-
# end
|
211
|
-
|
212
|
-
# def parse(input)
|
213
|
-
# case parser = @parser.call(input)
|
214
|
-
# when SucceedParser
|
215
|
-
# parser.parse(parser.remaining)
|
216
|
-
# when FailParser
|
217
|
-
# parser.parse(input)
|
218
|
-
# else
|
219
|
-
# raise
|
220
|
-
# end
|
221
|
-
# end
|
222
|
-
|
223
|
-
# end
|
224
154
|
|
225
155
|
|
226
156
|
class SeqParser
|
@@ -256,34 +186,6 @@ module Yaparc
|
|
256
186
|
end # of initialize
|
257
187
|
end # of SeqParser
|
258
188
|
|
259
|
-
# class SeqParser
|
260
|
-
# include Parsable
|
261
|
-
# def initialize(*parsers, &block)
|
262
|
-
# @parser = lambda do |input|
|
263
|
-
# args = []
|
264
|
-
# remains = parsers.inject(input) do |accumulator, parser|
|
265
|
-
# result = parser.parse(accumulator)
|
266
|
-
# if result == []
|
267
|
-
# break []
|
268
|
-
# else
|
269
|
-
# args << result[0][0]
|
270
|
-
# result[0][1]
|
271
|
-
# end
|
272
|
-
# end
|
273
|
-
# if remains == []
|
274
|
-
# []
|
275
|
-
# else
|
276
|
-
# retval = if block_given?
|
277
|
-
# yield(*args)
|
278
|
-
# else
|
279
|
-
# args.last
|
280
|
-
# end
|
281
|
-
# [[retval, remains]]
|
282
|
-
# end
|
283
|
-
# end
|
284
|
-
# end # of initialize
|
285
|
-
|
286
|
-
# end # of SeqParser
|
287
189
|
|
288
190
|
class AltParser
|
289
191
|
include Parsable
|
@@ -291,6 +193,7 @@ module Yaparc
|
|
291
193
|
@parser = lambda do |input|
|
292
194
|
initial_result = OK.new(:input => input)
|
293
195
|
final_result = Fail.new
|
196
|
+
# final_result = Error.new
|
294
197
|
parsers.each do |parser|
|
295
198
|
case result = parser.parse(initial_result.input)
|
296
199
|
when Fail
|
@@ -306,38 +209,25 @@ module Yaparc
|
|
306
209
|
end # of initialize
|
307
210
|
end
|
308
211
|
|
309
|
-
# class AltParser
|
310
|
-
# include Parsable
|
311
|
-
# def initialize(*parsers)
|
312
|
-
# @parser = lambda do |input|
|
313
|
-
# parsers.inject([]) do |accum, parser|
|
314
|
-
# result = parser.parse(input)
|
315
|
-
# if result == []
|
316
|
-
# result
|
317
|
-
# else
|
318
|
-
# break [result[0]]
|
319
|
-
# end
|
320
|
-
# end
|
321
|
-
# end
|
322
|
-
# end # of initialize
|
323
|
-
# end
|
324
212
|
|
325
213
|
|
326
214
|
class ApplyParser
|
327
215
|
include Parsable
|
328
216
|
def initialize(parser, &block)
|
329
217
|
@parser = lambda do |input|
|
330
|
-
|
331
|
-
|
332
|
-
|
218
|
+
case result = parser.parse(input)
|
219
|
+
when OK
|
220
|
+
SucceedParser.new(yield(result.value)).parse(result.input)
|
221
|
+
when Fail
|
333
222
|
FailParser.new.parse(input)
|
334
223
|
else
|
335
|
-
|
224
|
+
raise
|
336
225
|
end
|
337
226
|
end
|
338
227
|
end # of initialize
|
339
228
|
end # of ApplyParser
|
340
229
|
|
230
|
+
|
341
231
|
class StringParser
|
342
232
|
include Parsable
|
343
233
|
def initialize(string)
|
@@ -364,31 +254,6 @@ module Yaparc
|
|
364
254
|
end
|
365
255
|
end
|
366
256
|
|
367
|
-
# class StringParser
|
368
|
-
# include Parsable
|
369
|
-
# def initialize(string)
|
370
|
-
# @parser = lambda do |input|
|
371
|
-
# result = ItemParser.new.parse(string)
|
372
|
-
# if result == []
|
373
|
-
# SucceedParser.new(result)
|
374
|
-
# else
|
375
|
-
# SeqParser.new(
|
376
|
-
# CharParser.new(result[0][0]),
|
377
|
-
# StringParser.new(result[0][1]),
|
378
|
-
# SucceedParser.new(result[0][0] + result[0][1])
|
379
|
-
# ) do |char_result, string_result, succeed_result|
|
380
|
-
# succeed_result
|
381
|
-
# end
|
382
|
-
# end
|
383
|
-
# end
|
384
|
-
# end
|
385
|
-
|
386
|
-
# def parse(input)
|
387
|
-
# @parser.call(input).parse(input)
|
388
|
-
# end
|
389
|
-
# end
|
390
|
-
|
391
|
-
|
392
257
|
class RegexParser
|
393
258
|
include Parsable
|
394
259
|
|
@@ -403,26 +268,12 @@ module Yaparc
|
|
403
268
|
end
|
404
269
|
end
|
405
270
|
|
406
|
-
# class RegexParser
|
407
|
-
# include Parsable
|
408
|
-
|
409
|
-
# def initialize(regex)
|
410
|
-
# @parser = lambda do |input|
|
411
|
-
# if match = Regexp.new(regex).match(input)
|
412
|
-
# [[match[0],match.post_match]]
|
413
|
-
# else
|
414
|
-
# []
|
415
|
-
# end
|
416
|
-
# end
|
417
|
-
# end
|
418
|
-
# end
|
419
|
-
|
420
271
|
# permits zero or more applications of parser.
|
421
272
|
class ManyParser
|
422
273
|
include Parsable
|
423
|
-
def initialize(parser)
|
274
|
+
def initialize(parser, identity = "")
|
424
275
|
@parser = lambda do |input|
|
425
|
-
AltParser.new(ManyOneParser.new(parser), SucceedParser.new(
|
276
|
+
AltParser.new(ManyOneParser.new(parser, identity), SucceedParser.new(identity)).parse(input)
|
426
277
|
end
|
427
278
|
end
|
428
279
|
|
@@ -431,27 +282,14 @@ module Yaparc
|
|
431
282
|
end
|
432
283
|
end
|
433
284
|
|
434
|
-
# class ManyParser
|
435
|
-
# include Parsable
|
436
|
-
# def initialize(parser)
|
437
|
-
# @parser = lambda do |input|
|
438
|
-
# AltParser.new(ManyOneParser.new(parser), SucceedParser.new([])).parse(input)
|
439
|
-
# end
|
440
|
-
# end
|
441
|
-
|
442
|
-
# def parse(input)
|
443
|
-
# @parser.call(input)
|
444
|
-
# end
|
445
|
-
# end
|
446
|
-
|
447
285
|
# requires at least one successfull application of parser.
|
448
286
|
class ManyOneParser
|
449
287
|
include Parsable
|
450
|
-
def initialize(parser)
|
288
|
+
def initialize(parser, identity = "")
|
451
289
|
@parser = lambda do |input|
|
452
290
|
SeqParser.new(
|
453
291
|
parser,
|
454
|
-
ManyParser.new(parser)
|
292
|
+
ManyParser.new(parser, identity)
|
455
293
|
) do |head, tail|
|
456
294
|
head + tail
|
457
295
|
end
|
@@ -463,29 +301,6 @@ module Yaparc
|
|
463
301
|
end
|
464
302
|
end
|
465
303
|
|
466
|
-
# class ManyOneParser
|
467
|
-
# include Parsable
|
468
|
-
# def initialize(parser)
|
469
|
-
# @parser = lambda do |input|
|
470
|
-
# SeqParser.new(
|
471
|
-
# parser,
|
472
|
-
# ManyParser.new(parser)
|
473
|
-
# ) do |v, vs|
|
474
|
-
# if vs == []
|
475
|
-
# v
|
476
|
-
# else
|
477
|
-
# v + vs.to_s
|
478
|
-
# end
|
479
|
-
# end
|
480
|
-
# end
|
481
|
-
# end
|
482
|
-
|
483
|
-
# def parse(input)
|
484
|
-
# @parser.call(input).parse(input)
|
485
|
-
# end
|
486
|
-
# end
|
487
|
-
|
488
|
-
|
489
304
|
class ParserBase
|
490
305
|
include Parsable
|
491
306
|
|
@@ -502,14 +317,6 @@ module Yaparc
|
|
502
317
|
end
|
503
318
|
end
|
504
319
|
|
505
|
-
# class CharParser < ParserBase
|
506
|
-
|
507
|
-
# def initialize(char)
|
508
|
-
# equal_char = lambda {|i| i == char}
|
509
|
-
# @parser = SatisfyParser.new(equal_char)
|
510
|
-
# end
|
511
|
-
# end
|
512
|
-
|
513
320
|
|
514
321
|
class ZeroOneParser < ParserBase
|
515
322
|
def initialize(parser)
|
@@ -517,13 +324,6 @@ module Yaparc
|
|
517
324
|
end
|
518
325
|
end
|
519
326
|
|
520
|
-
# class ZeroOneParser < ParserBase
|
521
|
-
# def initialize(parser)
|
522
|
-
# @parser = AltParser.new(parser, SucceedParser.new([]))
|
523
|
-
# end
|
524
|
-
# end
|
525
|
-
|
526
|
-
|
527
327
|
class Ident < ParserBase
|
528
328
|
def initialize
|
529
329
|
@parser = SeqParser.new(
|
@@ -535,21 +335,6 @@ module Yaparc
|
|
535
335
|
end
|
536
336
|
end
|
537
337
|
|
538
|
-
# class Ident < ParserBase
|
539
|
-
# def initialize
|
540
|
-
# @parser = SeqParser.new(
|
541
|
-
# SatisfyParser.new(IS_LOWER),
|
542
|
-
# ManyParser.new(SatisfyParser.new(IS_ALPHANUM))
|
543
|
-
# ) do |v, vs|
|
544
|
-
# if vs == []
|
545
|
-
# v
|
546
|
-
# else
|
547
|
-
# v + vs.to_s
|
548
|
-
# end
|
549
|
-
# end
|
550
|
-
# end
|
551
|
-
# end
|
552
|
-
|
553
338
|
class Nat < ParserBase
|
554
339
|
def initialize
|
555
340
|
@parser = SeqParser.new(ManyOneParser.new(SatisfyParser.new(IS_DIGIT))) do |vs|
|
@@ -562,19 +347,6 @@ module Yaparc
|
|
562
347
|
end
|
563
348
|
end
|
564
349
|
|
565
|
-
# class Nat < ParserBase
|
566
|
-
|
567
|
-
# def initialize
|
568
|
-
# @parser = SeqParser.new(ManyOneParser.new(SatisfyParser.new(IS_DIGIT))) do |vs|
|
569
|
-
# if vs == []
|
570
|
-
# vs
|
571
|
-
# else
|
572
|
-
# vs.to_i
|
573
|
-
# end
|
574
|
-
# end
|
575
|
-
# end
|
576
|
-
# end
|
577
|
-
|
578
350
|
|
579
351
|
class Space < ParserBase
|
580
352
|
def initialize
|
@@ -584,15 +356,6 @@ module Yaparc
|
|
584
356
|
end
|
585
357
|
end
|
586
358
|
|
587
|
-
# class Space < ParserBase
|
588
|
-
|
589
|
-
# def initialize
|
590
|
-
# @parser = SeqParser.new(ManyParser.new(SatisfyParser.new(IS_SPACE))) do |vs|
|
591
|
-
# []
|
592
|
-
# end
|
593
|
-
# end
|
594
|
-
# end
|
595
|
-
|
596
359
|
class Token < ParserBase
|
597
360
|
|
598
361
|
def initialize(parser, prefix = Space.new, postfix = Space.new)
|
@@ -631,30 +394,6 @@ module Yaparc
|
|
631
394
|
end
|
632
395
|
end
|
633
396
|
|
634
|
-
# class Identifier
|
635
|
-
# include Parsable
|
636
|
-
# def initialize(*keywords)
|
637
|
-
# if keywords == []
|
638
|
-
# @parser = lambda do |input|
|
639
|
-
# Token.new(Ident.new)
|
640
|
-
# end
|
641
|
-
# else
|
642
|
-
# @parser = lambda do |input|
|
643
|
-
# keyword_parsers = keywords.map {|keyword| StringParser.new(keyword)}
|
644
|
-
# result = AltParser.new(*keyword_parsers).parse(input)
|
645
|
-
# unless result == []
|
646
|
-
# FailParser.new
|
647
|
-
# else
|
648
|
-
# Token.new(Ident.new)
|
649
|
-
# end
|
650
|
-
# end
|
651
|
-
# end
|
652
|
-
# end
|
653
|
-
|
654
|
-
# def parse(input)
|
655
|
-
# @parser.call(input).parse(input)
|
656
|
-
# end
|
657
|
-
# end
|
658
397
|
|
659
398
|
class Natural < ParserBase
|
660
399
|
|
@@ -663,12 +402,6 @@ module Yaparc
|
|
663
402
|
end
|
664
403
|
end
|
665
404
|
|
666
|
-
# class Natural < ParserBase
|
667
|
-
|
668
|
-
# def initialize
|
669
|
-
# @parser = Token.new(Nat.new)
|
670
|
-
# end
|
671
|
-
# end
|
672
405
|
|
673
406
|
class Symbol < ParserBase
|
674
407
|
|
@@ -687,8 +420,6 @@ module Yaparc
|
|
687
420
|
else
|
688
421
|
@tree = tree
|
689
422
|
end
|
690
|
-
|
691
423
|
end
|
692
424
|
end
|
693
|
-
|
694
425
|
end # of Yaparc
|
data/tests/test_parser.rb
CHANGED
@@ -214,15 +214,16 @@ class YaparcTest < Test::Unit::TestCase
|
|
214
214
|
# assert_equal [], result
|
215
215
|
# end
|
216
216
|
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
217
|
+
def test_apply_parse
|
218
|
+
is_digit = lambda {|i| i >= '0' and i <= '9'}
|
219
|
+
parser = ApplyParser.new(SatisfyParser.new(is_digit)) do |digit|
|
220
|
+
digit.to_i - '0'.to_i
|
221
|
+
end
|
222
222
|
|
223
|
-
|
224
|
-
|
225
|
-
|
223
|
+
result = parser.parse('7')
|
224
|
+
assert_equal 7, result.value
|
225
|
+
assert_equal "", result.input
|
226
|
+
end
|
226
227
|
|
227
228
|
def test_char_parse
|
228
229
|
parser = CharParser.new("a")
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.3
|
|
3
3
|
specification_version: 1
|
4
4
|
name: yaparc
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0.
|
7
|
-
date: 2008-01-
|
6
|
+
version: 0.0.9
|
7
|
+
date: 2008-01-11 00:00:00 +09:00
|
8
8
|
summary: Yet Another Combinator Parser Library
|
9
9
|
require_paths:
|
10
10
|
- lib
|