There are some semantic requirements:
all modules used must exist;
a module must share the rules mentioned to be used from that module;
all names in uses and
shares specifications in a module must be
unique;
a module must not define a rule for any name that it
uses;
a module must define rules for all names it
shares.
Modules are allowed to invoke each other: consider a programming language where declarations can include procedures, and procedures can include declarations, then the module for procedures would have:
+uses declaration from declaration.ixml
+shares procedure
and the module for declarations would have:
+uses procedure from procedure.ixml
+shares declaration
This illustrates that a uses specification is
different from, for instance, a #include
statement in C preprocessing, since uses only
ensures that the module will be present in the final grammar.
Note that a module can only share rules it defines; it is not permitted to share a rule from a different module like this:
+uses x, y from z.ixml
+shares x
So, having defined what a module looks like, we can now use it to define itself:
+uses ixml, name, s, rs from ixml.ixml; iri from iri.ixml
+shares module
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.