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.
- data/lib/peg.rb +31 -22
- 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
|
-
|
380
|
+
rules = rules.map {|rule| [rule.name, rule]}
|
381
|
+
@rules = Hash[rules]
|
381
382
|
end
|
382
383
|
|
383
384
|
def resolve
|
384
|
-
|
385
|
+
name, rule = @rules.first
|
386
|
+
_resolve(rule)
|
385
387
|
end
|
386
388
|
|
387
|
-
def _resolve
|
389
|
+
def _resolve(rule)
|
388
390
|
if rule.class == Reference
|
389
|
-
|
390
|
-
|
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
|
-
|
426
|
-
|
427
|
-
|
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
|
432
|
-
|
433
|
-
|
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.
|
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-
|
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
|