yaparc 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
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