Page 1 of 1

RelaxNG Dead end - modularity and duplicate includes

Posted: Fri Sep 14, 2007 2:36 am
by cefn
I'm trying to build a modular grammar for a trivial language built around a type system - which shouldn't be a problem in RelaxNG. Indeed it wasn't a problem at all, until I started to plug modules together. Then I get errors like...

"multiple definitions of start without "combine" attribute"

The reason for this is that several of the modules themselves depend on the same file. This is of course common in any pluggable modular language (as opposed to a language in which all dialects are organised in a strict hierarchy). E.g. a new dialect may combine an arbitrary subset of other dialects and extend them.

I've created a worked example of this limitation in which the basic language defines statements, expressions and a print statement for expressions. Modules extending this basic language include new constructs which need to be added to the definition of statement or the definition of expression- a trivial sort of example for a grammar I would think. However, it seems to have uncovered an insoluble problem in the way RelaxNG handles includes.

Two sub-dialects extend the basic language to include the statements and number expressions of arithmetic on the one hand, and statements and boolean expressions of logic on the other hand. Of course, each of these needs to refer to (include) the basic language grammar, where expression and statement are defined, and add new choices for what a statement or expression might be. This is all fine so far.

Finally, I attempt to use both arithmetic and logic together by including them both. At this point, there are two includes of the basic grammar - one in the arithmetic definitions, and another in the logic definitions.

It turns out that basic.rng then conflicts with itself - since it tries to redefine all the elements which were already defined in the earlier include of the same file. There's no equivalent to the PHP 'include_once'. In other words, only include it if it's not already included.

My question: What's the proper way to approach this kind of composition. I'm missing something major here.

The worked example can be downloaded from...

http://cefn.com/blog/files/modularity.zip

Combining Grammars

Posted: Sun Sep 16, 2007 1:49 pm
by cefn
Really hoping someone can help out with this as I'm really stuck and things are stalled without a solution. The RelaxNG mailing lists are offline and I don't know where else to seek help on this one.

The test example which generates the issue is really simple - so much so that it's inlined below...

[code]
<?xml version="1.0" encoding="UTF-8"?>
<grammar
xmlns="http://relaxng.org/ns/structure/1.0"
xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">

<include href="logic.rng"/>
<include href="arithmetic.rng"/>

</grammar>
[/code]

...and if this can't be made to work, then I can't consider RelaxNG to be a modular schema definition language.

I'm hoping it's because I've pursued the wrong representation and it can be fixed by a simple modification of the definitions I've made. I've uploaded the simplified test case to
[url]http://cefn.com/blog/files/modularity.zip[/url]

Posted: Mon Sep 17, 2007 12:36 pm
by george
Hi,

One possibility to work around this problem is to add a combine="choice" to the patterns in the schema that is included twice.
basic.rng

Code: Select all


<?xml version="1.0" encoding="UTF-8"?>
<grammar
xmlns="http://relaxng.org/ns/structure/1.0"
xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">

<start combine="choice">
<ref name="program"/>
</start>

<define name="program" combine="choice">
<element name="program">
<oneOrMore>
<ref name="statement"/>
</oneOrMore>
</element>
</define>

<define name="statement" combine="choice">
<ref name="print" />
</define>

<define name="expr" combine="choice">
<notAllowed/>
</define>

<define name="print" combine="choice">
<element name="print">
<ref name="expr"/>
</element>
</define>

</grammar>
Best Regards,
George

Combine=choice

Posted: Mon Sep 17, 2007 1:56 pm
by cefn
I'm a bit concerned that the workaround will break the grammar, though, since it will reintroduce options in the definitions which may themselves have been redefined since the first inclusion.

I'll give it a go, though and stay eagle-eyed for any issues arising.