peg 0.0.1 → 0.0.4

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.
Files changed (2) hide show
  1. data/lib/peg.rb +31 -22
  2. metadata +2 -2
data/lib/peg.rb CHANGED
@@ -377,32 +377,27 @@ module PEG
377
377
 
378
378
  class ReferenceResolver
379
379
  def initialize(rules)
380
- @rules = rules
380
+ rules = rules.map {|rule| [rule.name, rule]}
381
+ @rules = Hash[rules]
381
382
  end
382
383
 
383
384
  def resolve
384
- _resolve!(@rules[0])
385
+ name, rule = @rules.first
386
+ _resolve(rule)
385
387
  end
386
388
 
387
- def _resolve!(rule)
389
+ def _resolve(rule)
388
390
  if rule.class == Reference
389
- resolved_rule = reference(rule.reference)
390
- if resolved_rule.class == Reference
391
- _resolve!(resolved_rule)
392
- else
393
- resolved_rule
394
- end
395
- elsif rule.children.length > 0
396
- rule.children.map! {|child| _resolve!(child)}
397
- rule
391
+ rule = @rules[rule.reference]
392
+ _resolve(rule)
398
393
  else
394
+ old_children = rule.children
395
+ rule.children = [] # avoid infinite reqursion of _resolve
396
+ new_children = old_children.map {|child| _resolve(child)}
397
+ rule.children = new_children
399
398
  rule
400
399
  end
401
400
  end
402
-
403
- def reference(name)
404
- @rules.find {|r| r.name == name} || raise("rule `#{name}` not found")
405
- end
406
401
  end
407
402
 
408
403
  class Language
@@ -421,16 +416,30 @@ module PEG
421
416
  @@default = block
422
417
  end
423
418
 
419
+ def to_lambda(&block)
420
+ obj = Object.new
421
+ obj.define_singleton_method(:_, &block)
422
+ return obj.method(:_).to_proc
423
+ end
424
+
424
425
  def eval(source)
425
- grammar_source = @@rules.values.join("\n")
426
- node = Grammar.new(grammar_source).parse(source)
427
- _eval(node)
426
+ if source.class == String
427
+ grammar_source = @@rules.values.join("\n")
428
+ source = Grammar.new(grammar_source).parse(source)
429
+ end
430
+ _eval(source)
428
431
  end
429
432
 
430
433
  def _eval(node)
431
- block = @@blocks.fetch(node.name, @@default)
432
- children = node.children.map {|child| _eval(child)}
433
- instance_exec(node, children, &block)
434
+ block = @@blocks[node.name] || @@default
435
+ if block.arity == 2
436
+ children = node.children.map {|child| _eval(child)}
437
+ instance_exec(node, children, &block)
438
+ elsif block.arity == 1
439
+ instance_exec(node, &block)
440
+ else
441
+ raise "`rule` expects a block with signature |node| or |node, children|"
442
+ end
434
443
  end
435
444
  end
436
445
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: peg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-06-02 00:00:00.000000000 Z
12
+ date: 2013-08-12 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Parsing Expression Grammar implmentation
15
15
  email: vladimir@keleshev.com