Permalink
Browse files

+ Entity made simpler

Entity now takes only a block as argument. It could also be called lazy
entity now ;)
  • Loading branch information...
1 parent 9b5e512 commit b3259a438aaad810ce1f150eb9a97541b06e06cf @kschiess committed Feb 22, 2011
View
11 HISTORY.txt
@@ -1,8 +1,5 @@
= 1.2.0 / ???
- + Visitors now should have methods that all begin with 'visit_*'. #str
- becomes #visit_str.
-
+ Parslet::Parser is now also a grammar atom, it can be composed freely with
other atoms. (str('f') >> MiniLispParser.new >> str('b'))
@@ -11,6 +8,14 @@
source offset. This has also bought us a slight speedup.
+ require 'parslet/convenience' now brings #parse_with_debug to all parslets.
+
+ INTERNALLY
+
+ + Visitors now should have methods that all begin with 'visit_*'. #str
+ becomes #visit_str.
+
+ + Parslet::Atoms::Entity now takes only a block argument instead of context
+ and block.
= 1.1.1 / 4Feb2011
View
10 lib/parslet.rb
@@ -96,8 +96,14 @@ module ClassMethods
def rule(name, &definition)
define_method(name) do
@rules ||= {} # <name, rule> memoization
- @rules[name] or
- (@rules[name] = Atoms::Entity.new(name, self, definition))
+ return @rules[name] if @rules.has_key?(name)
+
+ # Capture the self of the parser class along with the definition.
+ definition_closure = proc {
+ self.instance_eval(&definition)
+ }
+
+ @rules[name] = Atoms::Entity.new(name, &definition_closure)
end
end
end
View
7 lib/parslet/atoms/entity.rb
@@ -9,12 +9,11 @@
# using the structuring method Parslet.rule.
#
class Parslet::Atoms::Entity < Parslet::Atoms::Base
- attr_reader :name, :context, :block
- def initialize(name, context, block) # :nodoc:
+ attr_reader :name, :block
+ def initialize(name, &block) # :nodoc:
super()
@name = name
- @context = context
@block = block
end
@@ -23,7 +22,7 @@ def try(source, context) # :nodoc:
end
def parslet
- @parslet ||= context.instance_eval(&block).tap { |p|
+ @parslet ||= @block.call.tap { |p|
raise_not_implemented unless p
}
end
View
7 lib/parslet/atoms/transform.rb
@@ -28,11 +28,10 @@ def visit_lookahead(positive, parslet)
Parslet::Atoms::Lookahead.new(positive, parslet.accept(self))
end
- # TODO: at least roll context and block into one lambda.
- def visit_entity(name, context, block)
+ def visit_entity(name, block)
transformer = self
- transformed_block = proc { context.instance_eval(&block).accept(transformer) }
- Parslet::Atoms::Entity.new(name, context, transformed_block)
+ transformed_block = proc { block.call.accept(transformer) }
+ Parslet::Atoms::Entity.new(name, &transformed_block)
end
def visit_named(name, parslet)
View
2 lib/parslet/atoms/visitor.rb
@@ -21,7 +21,7 @@ class Entity
# Call back visitors #entity method. See parslet/export for an example.
#
def accept(visitor)
- visitor.visit_entity(name, context, block)
+ visitor.visit_entity(name, block)
end
end
View
8 lib/parslet/export.rb
@@ -18,8 +18,8 @@ def visit_re(match)
match.to_s
end
- def visit_entity(name, ctx, block)
- context.deferred(name, [ctx, block])
+ def visit_entity(name, block)
+ context.deferred(name, block)
"(#{context.mangle_name(name)})"
end
@@ -88,13 +88,13 @@ def pretty_print(name, parslet) # :nodoc:
# @todo is constantly filled by the visitor (see #deferred). We
# keep going until it is empty.
break if @todo.empty?
- name, (context, block) = @todo.shift
+ name, block = @todo.shift
# Track what rules we've already seen. This breaks loops.
next if seen.include?(name)
seen << name
- output << rule(name, context.instance_eval(&block))
+ output << rule(name, block.call)
end
output << "end\n"
View
4 spec/parslet/atoms/entity_spec.rb
@@ -2,7 +2,7 @@
describe Parslet::Atoms::Entity do
context "when constructed with str('bar') inside" do
- let(:named) { Parslet::Atoms::Entity.new('name', self, proc { Parslet.str('bar') }) }
+ let(:named) { Parslet::Atoms::Entity.new('name', &proc { Parslet.str('bar') }) }
it "should parse 'bar' without raising exceptions" do
named.parse('bar')
@@ -20,7 +20,7 @@
end
end
context "when constructed with empty block" do
- let(:entity) { Parslet::Atoms::Entity.new('name', self, proc { }) }
+ let(:entity) { Parslet::Atoms::Entity.new('name', &proc { }) }
it "should raise NotImplementedError" do
lambda {
View
6 spec/parslet/atoms/transform_spec.rb
@@ -71,14 +71,14 @@ def visit_lookahead(positive, parslet)
end
context "entity" do
class ModifyAll
- def visit_entity(name, context, block)
- super(name, context, block)
+ def visit_entity(name, block)
+ super(name, block)
end
end
it "should lazily produce a transformed grammar" do
block = proc { str('bar') }
apply(
- Parslet::Atoms::Entity.new(:foo, self, block)
+ Parslet::Atoms::Entity.new(:foo, &block)
).should parse('rab')
end
end
View
4 spec/parslet/atoms/visitor_spec.rb
@@ -53,9 +53,9 @@
end
end
describe Parslet::Atoms::Entity do
- let(:parslet) { Parslet::Atoms::Entity.new('foo', :context, lambda {}) }
+ let(:parslet) { Parslet::Atoms::Entity.new('foo', &lambda {}) }
it "should call back visitor" do
- visitor.should_receive(:visit_entity).with('foo', :context, Proc).once
+ visitor.should_receive(:visit_entity).with('foo', Proc).once
parslet.accept(visitor)
end

0 comments on commit b3259a4

Please sign in to comment.