Circular Dependency Loading

24 views
Skip to first unread message

ET

unread,
Oct 14, 2010, 11:11:42 PM10/14/10
to Treetop Development
I am using treetop to construct a grammar but am having problems with
what seems to be a circular dependency.

Consider the following structure:

test.rb
lib/A.treetop
lib/B.treetop
lib/AB.treetop
lib/all.rb

And the sources for the files

# test.rb
require File.dirname(__FILE__) + "/lib/all"

# lib/A.treetop
grammar A
include AB
end

# lib/B.treetop
grammar B
include AB
end

# lib/AB.treetop
grammar AB
include A
include B
end

# lib/all.rb
require 'treetop'

require File.dirname(__FILE__) + '/A'
require File.dirname(__FILE__) + '/B'
require File.dirname(__FILE__) + '/AB'

It's very obvious that I've introduced a circular dependency.

Now when I run test.rb

ruby test.rb

I receive the following error:

/home/eric/.rvm/gems/ruby-1.9.2-rc2/gems/treetop-1.4.8/lib/treetop/
compiler/grammar_compiler.rb:42:in `class_eval': uninitialized
constant A::AB (NameError)
....

meaning that it could not include the 'AB' grammar in the 'A' grammar
since it's after it in the 'all.rb' file.

However, this circular dependency is necessary.

Consider this pseudo-grammar where it would be applicable:

# Statement file
include ForStatement
include SwitchStatement
statement -> for_statement / switch_statement / other_statement

# ForStatement file
include Statement
for_statement -> 'for (' expr ')' statement

As you can see, the for loop can contain other statements inside it.
But I cannot accomplish this unless all the rules are in the same
file.

Can someone please point me in the right direction on how to
accomplish this if it's even possible?

Clifford Heath

unread,
Oct 14, 2010, 11:28:21 PM10/14/10
to treet...@googlegroups.com
On 15/10/2010, at 2:11 PM, ET wrote:
> However, this circular dependency is necessary.

I don't believe that's true. You need to define 'statement' in one
grammar, and that grammar needs to include all the modules
that provide statements.

A grammar may call rules which it doesn't either include or define,
so this is perfectly acceptable. Your "for" statement grammar can
call "statement" without defining it or including a module that defines
it.

However, another feature of which you might not be aware is that
an included grammar may override a rule in the grammar into which
it's included, and can call "super" to invoke the overridden rule.

So if I have a grammar which defines 'statement' with five alternatives,
and I want to include a grammar which defines a sixth alternative (say
an "until" statement), I can say:

rule statement
until_statement / super
end

in my included grammar. This first tries for an until_statement, then
falls back to the base grammar's "statement" rule.

Clifford Heath.

ET

unread,
Oct 23, 2010, 7:52:13 PM10/23/10
to Treetop Development
Ahh... this makes good sense. Thanks Clifford.
Reply all
Reply to author
Forward
0 new messages