Hi,
I have a complex application that originally included two treetop grammars;
one for a C like language, and another for a Ruty style templating engine. I
have split the former into a language grammar and an infix notation
expression grammar, so I need to "compose" these, by which I mean include
the expression grammar into the language grammar. My ultimate goal is to
reuse the expression grammar in the templating grammar also, to give my
template syntax more oomph.
The approved way to do this, as per the rdocs, is something like:
class FooBarParser < Parslet::Parser
root(:foobar)
rule(:foobar) do
FooParser.new.as(:foo) >> BarParser.new.as(:bar)
end
end
But I was wondering if there were any disadvantages to reusing the same
parser object, like this:
class BarFooParser < Parslet::Parser
def initialize(*args)
super(*args)
@foo = FooParser.new
@bar = BarParser.new
end
root(:barfoo)
rule(:barfoo) do
@bar.as(:bar) >> @foo.as(:foo)
end
end
or even this:
class FooBazParser < Parslet::Parser
class << self; attr_accessor :foo, :baz; end
def initialize(*args)
super(*args)
self.class.foo ||= FooParser.new
self.class.baz ||= BazParser.new
end
root(:foobaz)
rule(:foobaz) do
self.class.foo.as(:foo) >> self.class.baz.as(:baz)
end
end
These all work ok in my simple test cases, but I'm wondering if parsers
store any state which might make this approach go wrong once the parser
instance is referenced in multiple rules, or on multiple branches of an
ordered choice expression? And what's the overhead of a Parser.new ? Is it
even worth bothering?
cheers
ant