yaparc 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README CHANGED
@@ -138,17 +138,7 @@ The ManyOneParser requires at least one successfull application of parser.
138
138
 
139
139
  == Define your own parser
140
140
 
141
-
142
- There are two ways to construct parser. One is to inherit from Yaparc::ParserBase class.
143
-
144
- class StringMatch < Yaparc::ParserBase
145
-
146
- def initialize(literal)
147
- @parser = Yaparc::Token.new(Yaparc::StringParser.new(literal))
148
- end
149
- end
150
-
151
- The other is to inherit from Yaparc::AbstractParser class.
141
+ In order to construct parsers, you make parser class to be inherited from Yaparc::AbstractParser class.
152
142
 
153
143
  class Identifier < Yaparc::AbstractParser
154
144
  def initialize
data/lib/yaparc.rb CHANGED
@@ -39,12 +39,10 @@ module Yaparc
39
39
  result = result.parse(input)
40
40
  else
41
41
  if block_given?
42
- # @tree = yield result.value
43
42
  result.value = yield result.value
44
43
  @tree = result
45
44
  else
46
45
  @tree = result.value
47
- # @tree = result.parse(input)
48
46
  end
49
47
  result
50
48
  end
@@ -59,11 +57,11 @@ module Yaparc
59
57
  def included(mod)
60
58
  end
61
59
 
62
- def define_parser(&block)
63
- @@cparser = lambda do
64
- yield
65
- end
66
- end
60
+ # def define_parser(&block)
61
+ # @@cparser = lambda do
62
+ # yield
63
+ # end
64
+ # end
67
65
  end
68
66
  end # of Module Parsable
69
67
 
@@ -104,6 +102,33 @@ module Yaparc
104
102
  end
105
103
  end
106
104
 
105
+ class ZeroOneParser
106
+ include Parsable
107
+ def initialize(parser, identity = [])
108
+ @parser = lambda do |input|
109
+ case result = parser.parse(input)
110
+ when Result::Fail
111
+ SucceedParser.new(identity)
112
+ when Result::Error
113
+ Result::Error.new(:value => result.value, :input => result.input)
114
+ when Result::OK
115
+ result
116
+ else
117
+ raise
118
+ end
119
+
120
+ # AltParser.new(parser, SucceedParser.new(identity))
121
+ # case result = AltParser.new(parser, SucceedParser.new(identity)).parse(input)
122
+ # if input.nil? or input.empty?
123
+ # Result::Fail.new(:input => input)
124
+ # else
125
+ # Result::OK.new(:value => input[0..0],:input => input[1..input.length])
126
+ # end
127
+
128
+ end
129
+ end
130
+ end
131
+
107
132
  class SatisfyParser
108
133
  include Parsable
109
134
  def initialize(predicate)
@@ -197,7 +222,8 @@ module Yaparc
197
222
  initial_result = Result::OK.new(:input => input)
198
223
  final_result = Result::Fail.new(:input => input)
199
224
  parsers.each do |parser|
200
- case result = parser.parse(initial_result.input)
225
+ # case result = parser.parse(initial_result.input)
226
+ case result = parser.parse(input)
201
227
  when Result::Fail
202
228
  next
203
229
  when Result::Error
@@ -256,32 +282,60 @@ module Yaparc
256
282
 
257
283
  class RegexParser
258
284
  include Parsable
259
-
260
- def initialize(regex)
285
+
286
+ def initialize(regex, &block)
287
+ @regex = regex
261
288
  @parser = lambda do |input|
262
289
  if match = Regexp.new(regex).match(input)
263
- Result::OK.new(:value => match[0], :input => match.post_match)
290
+ if block_given?
291
+ SucceedParser.new(yield(*match.to_a[1..match.to_a.length])).parse(match.post_match)
292
+ else
293
+ Result::OK.new(:value => match[0], :input => match.post_match)
294
+ end
264
295
  else
265
296
  Result::Fail.new(:input => input)
266
297
  end
267
298
  end
268
299
  end
300
+
301
+ def parse_with_parameter(input)
302
+ if match = Regexp.new(@regex).match(input)
303
+ if block_given?
304
+ yield match.to_a[1..match.to_a.length]
305
+ else
306
+ Result::OK.new(:value => match, :input => match.post_match)
307
+ end
308
+ else
309
+ Result::Fail.new(:input => input)
310
+ end
311
+ end
269
312
  end
313
+ # class RegexParser
314
+ # include Parsable
315
+
316
+ # def initialize(regex)
317
+ # @parser = lambda do |input|
318
+ # if match = Regexp.new(regex).match(input)
319
+ # Result::OK.new(:value => match[0], :input => match.post_match)
320
+ # else
321
+ # Result::Fail.new(:input => input)
322
+ # end
323
+ # end
324
+ # end
325
+ # end
270
326
 
271
327
  # permits zero or more applications of parser.
272
328
  class ManyParser
273
329
  include Parsable
274
- # def initialize(parser, identity = "")
275
330
  def initialize(parser, identity = [])
276
331
  @parser = lambda do |input|
277
- # AltParser.new(ManyOneParser.new(parser, identity), SucceedParser.new(identity)).parse(input)
278
332
  AltParser.new(ManyOneParser.new(parser, identity), SucceedParser.new(identity))
279
333
  end
280
334
  end
281
335
 
282
- def parse(input)
283
- @parser.call(input).parse(input)
284
- end
336
+ # def parse(input)
337
+ # @parser.call(input).parse(input)
338
+ # end
285
339
  end
286
340
 
287
341
  # requires at least one successfull application of parser.
@@ -303,107 +357,91 @@ module Yaparc
303
357
  end
304
358
  end
305
359
 
306
- class ParserBase
307
- include Parsable
308
-
309
- def parse(input)
310
- @parser.parse(input)
311
- end
312
- end
313
360
 
314
- class CharParser < ParserBase
315
361
 
316
- def initialize(char)
317
- equal_char = lambda {|i| i == char}
318
- @parser = SatisfyParser.new(equal_char)
319
- end
320
- end
321
-
322
- class ZeroOneParser < ParserBase
323
- def initialize(parser)
324
- @parser = AltParser.new(parser, SucceedParser.new([])) # Is it OK?
325
- end
326
- end
327
362
 
328
- class Ident < ParserBase
329
- def initialize
330
- @parser = SeqParser.new(
331
- SatisfyParser.new(IS_LOWER),
332
- ManyParser.new(SatisfyParser.new(IS_ALPHANUM),"")
333
- ) do |head, tail|
334
- head + tail
335
- end
336
- end
337
- end
338
-
339
- class Nat < ParserBase
340
- def initialize
341
- @parser = SeqParser.new(ManyOneParser.new(SatisfyParser.new(IS_DIGIT),"")) do |vs|
342
- if vs == ""
343
- vs
344
- else
345
- vs.to_i
346
- end
347
- end
348
- end
349
- end
350
-
351
-
352
- class Space < ParserBase
363
+ class SpaceParser
364
+ include Parsable
353
365
  def initialize
354
- @parser = SeqParser.new(ManyParser.new(SatisfyParser.new(IS_SPACE),"")) do |vs|
355
- SucceedParser.new([])
366
+ @parser = lambda do |input|
367
+ SeqParser.new(ManyParser.new(SatisfyParser.new(IS_SPACE),""))
356
368
  end
357
369
  end
358
370
  end
359
371
 
360
- class WhiteSpace < ParserBase
372
+ class WhiteSpaceParser
373
+ include Parsable
361
374
  def initialize
362
- @parser = SeqParser.new(ManyParser.new(SatisfyParser.new(IS_WHITESPACE),"")) do |vs|
363
- SucceedParser.new([])
375
+ @parser = lambda do |input|
376
+ SeqParser.new(ManyParser.new(SatisfyParser.new(IS_WHITESPACE),''))
364
377
  end
365
378
  end
366
379
  end
367
380
 
368
- class Token < ParserBase
381
+ class TokenizeParser
382
+ include Parsable
369
383
  attr_accessor :prefix, :postfix
370
384
 
371
- def initialize(parser, prefix = WhiteSpace.new, postfix = WhiteSpace.new)
372
- @prefix, @postfix = prefix, postfix
373
- @parser = SeqParser.new(@prefix, parser, @postfix) do |_, vs, _|
374
- vs
385
+ def initialize(parser, args = { }, &block)
386
+ @parser = lambda do |input|
387
+ @prefix = args[:prefix] ? args[:prefix] : WhiteSpaceParser.new
388
+ @postfix = args[:postfix] ? args[:postfix] : WhiteSpaceParser.new
389
+ if block_given?
390
+ yield self
391
+ SeqParser.new(@prefix, parser, @postfix) do |_, vs, _|
392
+ vs
393
+ end
394
+ else
395
+ SeqParser.new(@prefix, parser, @postfix) do |_, vs, _|
396
+ vs
397
+ end
398
+ end
375
399
  end
376
400
  end
377
401
  end
378
402
 
379
- class Tokenize < ParserBase
380
- attr_accessor :prefix, :postfix
403
+ # class Tokenize < ParserBase
404
+ # attr_accessor :prefix, :postfix
381
405
 
382
- def initialize(parser, &block)
383
- @prefix, @postfix = WhiteSpace.new,WhiteSpace.new
384
- yield self
385
- @parser = SeqParser.new(@prefix, parser, @postfix) do |_, vs, _|
386
- vs
406
+ # def initialize(parser, &block)
407
+ # @prefix, @postfix = WhiteSpace.new,WhiteSpace.new
408
+ # yield self
409
+ # @parser = SeqParser.new(@prefix, parser, @postfix) do |_, vs, _|
410
+ # vs
411
+ # end
412
+ # end
413
+ # end
414
+
415
+ class LiteralParser
416
+ include Parsable
417
+ def initialize(literal)
418
+ @parser = lambda do |input|
419
+ TokenizeParser.new(StringParser.new(literal))
387
420
  end
388
421
  end
389
422
  end
390
423
 
391
424
  # Refer to http://www.cs.nott.ac.uk/~gmh/monparsing.pdf, p.23
425
+
392
426
  class Identifier
393
- include Parsable
427
+ include Yaparc::Parsable
428
+ @@identifier_regex = ::Yaparc::RegexParser.new(/\A[a-zA-Z_]+[a-zA-Z0-9_]*/)
429
+
394
430
  def initialize(*keywords)
395
431
  if keywords == []
396
432
  @parser = lambda do |input|
397
- Token.new(Ident.new)
433
+ TokenizeParser.new(@@identifier_regex)
434
+ # Yaparc::Token.new(@@identifier_regex)
398
435
  end
399
436
  else
400
437
  @parser = lambda do |input|
401
- keyword_parsers = keywords.map {|keyword| StringParser.new(keyword)}
402
- case result = AltParser.new(*keyword_parsers).parse(input)
403
- when Result::OK
404
- FailParser.new
438
+ keyword_parsers = keywords.map {|keyword| Yaparc::StringParser.new(keyword)}
439
+ case result = Yaparc::AltParser.new(*keyword_parsers).parse(input)
440
+ when Yaparc::Result::OK
441
+ Yaparc::FailParser.new
405
442
  else # Result::Fail or Result::Error
406
- Token.new(Ident.new)
443
+ TokenizeParser.new(@@identifier_regex)
444
+ # Yaparc::Token.new(@@identifier_regex)
407
445
  end
408
446
  end
409
447
  end
@@ -414,22 +452,148 @@ module Yaparc
414
452
  end
415
453
  end
416
454
 
455
+ # class ParserBase
456
+ # include Parsable
457
+
458
+ # def parse(input)
459
+ # @parser.parse(input)
460
+ # end
461
+ # end
462
+
463
+ class CharParser
464
+ include Parsable
465
+
466
+ def initialize(char)
467
+ equal_char = lambda {|i| i == char}
468
+ @parser = lambda do |input|
469
+ SatisfyParser.new(equal_char)
470
+ end
471
+ end
472
+ end
473
+ # class CharParser < ParserBase
474
+
475
+ # def initialize(char)
476
+ # equal_char = lambda {|i| i == char}
477
+ # @parser = SatisfyParser.new(equal_char)
478
+ # end
479
+ # end
417
480
 
418
- class Natural < ParserBase
481
+ # class ZeroOneParser < ParserBase
482
+ # def initialize(parser, identity = [])
483
+ # @parser = AltParser.new(parser, SucceedParser.new(identity)) # Is it OK?
484
+ # end
485
+ # end
419
486
 
487
+ class Ident
488
+ include Parsable
489
+ def initialize
490
+ @parser = lambda do |input|
491
+ SeqParser.new(
492
+ SatisfyParser.new(IS_LOWER),
493
+ ManyParser.new(SatisfyParser.new(IS_ALPHANUM),"")
494
+ ) do |head, tail|
495
+ head + tail
496
+ end
497
+ end
498
+ end
499
+ end
500
+ # class Ident < ParserBase
501
+ # def initialize
502
+ # @parser = SeqParser.new(
503
+ # SatisfyParser.new(IS_LOWER),
504
+ # ManyParser.new(SatisfyParser.new(IS_ALPHANUM),"")
505
+ # ) do |head, tail|
506
+ # head + tail
507
+ # end
508
+ # end
509
+ # end
510
+
511
+ class Nat
512
+ include Parsable
420
513
  def initialize
421
- @parser = Token.new(Nat.new)
514
+ @parser = lambda do |input|
515
+ SeqParser.new(ManyOneParser.new(SatisfyParser.new(IS_DIGIT),"")) do |vs|
516
+ if vs == ""
517
+ vs
518
+ else
519
+ vs.to_i
520
+ end
521
+ end
522
+ end
523
+ end
524
+ end
525
+
526
+ # class Nat < ParserBase
527
+ # def initialize
528
+ # @parser = SeqParser.new(ManyOneParser.new(SatisfyParser.new(IS_DIGIT),"")) do |vs|
529
+ # if vs == ""
530
+ # vs
531
+ # else
532
+ # vs.to_i
533
+ # end
534
+ # end
535
+ # end
536
+ # end
537
+
538
+ # class Space < ParserBase
539
+ # def initialize
540
+ # @parser = SeqParser.new(ManyParser.new(SatisfyParser.new(IS_SPACE),"")) do |vs|
541
+ # SucceedParser.new([])
542
+ # end
543
+ # end
544
+ # end
545
+
546
+ # class WhiteSpace < ParserBase
547
+ # def initialize
548
+ # @parser = SeqParser.new(ManyParser.new(SatisfyParser.new(IS_WHITESPACE),"")) do |vs|
549
+ # SucceedParser.new([])
550
+ # end
551
+ # end
552
+ # end
553
+
554
+ # class Token < ParserBase
555
+ # attr_accessor :prefix, :postfix
556
+
557
+ # def initialize(parser, prefix = WhiteSpace.new, postfix = WhiteSpace.new)
558
+ # @prefix, @postfix = prefix, postfix
559
+ # @parser = SeqParser.new(@prefix, parser, @postfix) do |_, vs, _|
560
+ # vs
561
+ # end
562
+ # end
563
+ # end
564
+
565
+ class Natural
566
+ include Parsable
567
+ def initialize(args = {})
568
+ @parser = lambda do |input|
569
+ TokenizeParser.new(Nat.new, args)
570
+ end
422
571
  end
423
572
  end
573
+ # class Natural < ParserBase
424
574
 
575
+ # def initialize
576
+ # @parser = Token.new(Nat.new)
577
+ # end
578
+ # end
425
579
 
426
- class Symbol < ParserBase
427
580
 
428
- def initialize(literal)
429
- @parser = Token.new(StringParser.new(literal))
581
+ class Symbol
582
+ include Parsable
583
+ def initialize(literal, args = {})
584
+ @parser = lambda do |input|
585
+ LiteralParser.new(literal)
586
+ end
430
587
  end
431
588
  end
432
589
 
590
+ # class Symbol < ParserBase
591
+
592
+ # def initialize(literal)
593
+ # @parser = Token.new(StringParser.new(literal))
594
+ # end
595
+ # end
596
+
433
597
  class AbstractParser
434
598
  include Parsable
435
599