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.