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