The Structure of a Module

A module consists of an otherwise normal ixml grammar, preceded by specifications of rules used from other modules and what is shared for use from this module.

A specification of what to use from another module lists the rules needed from each module it uses. Such a specification should be recognisable as different from an ixml rule.

The character to signal such a specification has been chosen as "+", though any character that doesn't start the first ixml rule in a grammar could have been used in the design; ixml rules can start with namestart characters, "-", "^" (and "@" but it is not possible to start the first rule of a grammar with that character):

+uses css from css.ixml

and

+uses iri, url, uri, urn from uri.ixml

This specifies which module to use, and which rules from that module are intended to be used.

It is possible to combine them

+uses css from css.ixml; iri, url, uri, urn from uri.ixml

The specification of what is allowable to be used from a module is similar:

+shares iri, url, uri, urn

There are two main choices for a grammar for these. The first literally recognises the structure as it is specified above:

module: s, (uses; shares)*, ixml.
           uses: -"+uses", rs, from++(-";", s).
         shares: -"+shares", rs, entries.
           from: entries, rs, -"from", rs, location, s.
       -entries: share++(-",", s).
          share: @name, s.
        @source: iri.

where s is the regular ixml rule for optional whitespace, rs for required whitespace, name the rule for a rule name, ixml the rule for an ixml grammar, and iri, not defined here, representing an internationalised URI [iri], allowing the use of grammars from external sources, such as:

+uses iri from https://example.com/ixml/modules/iri.ixml

For a specification like

+uses css from css.ixml; iri, url, uri, urn from uri.ixml

this produces a resulting structure like

<uses>
            <from source='css.ixml'>
               <share name='css'/>
            </from>
            <from source='iri.ixml'>
               <share name='iri'/>
               <share name='url'/>
               <share name='uri'/>
               <share name='urn'/>
            </from>
         </uses>

Alternatively, the grammar could look like:

module: s, (multiuse; shares)*, ixml.
         -multiuse: -"+uses", rs, uses++(-";", s).
            shares: -"+shares", rs, entries.
              uses: entries, rs, -"from", rs, from.
          -entries: share++(-",", s).
             share: @name, s.
             @from: iri, s.

where the resulting structure then looks like:

<uses from='css.ixml'>
            <share name='css'/>
         </uses>
         <uses from='uri.ixml'>
            <share name='iri'/>
            <share name='url'/>
            <share name='uri'/>
            <share name='urn'/>
         </uses>

The advantage of the latter version is that processing is slightly easier, since shallower, with a slight disadvantage with respect to round-tripping, since the two forms

+uses css from css.ixml; iri, url, uri, urn from uri.ixml

and

+uses css from css.ixml
         +uses iri, url, uri, urn from uri.ixml

are no longer distinguishable on roundtripping, since they produce the same serialisation.