Steven Pemberton
This proposal is for an ixml preprocessor that permits the use of libraries of ixml grammars to be invoked by another grammar.
The result is a single ixml grammar, with no rule-name clashes. This involves renaming rules with name clashes in the libraries, using ixml renaming, so that the resultant XML serialisations remain the same. The invoking grammar remains unchanged.
+use css from css.ixml; iri, uri, urn from iri.ixml; xpath from xpath.ixml . xforms: head, body. head: title, style?, model*. title: -"title ", ~[#a]+, -#a. style: -"style ", css. model: (instance; bind; submission; action)*. instance: "instance ", id, resource. @resource: iri. bind: ref, mip*, bind*. @ref: xpath. body: (control; action)* etc.
use: -"+", s, -"use", rs, library++(-";", s), -".". library: rulenames, -"from", rs, name, s. -rulenames: entry++(-",", s). entry: name, s.
Restrictions:
entry
names must be unique.entry
names.+use css from css.ixml; iri, uri, urn from iri.ixml; xpath from xpath.ixml . <use> <library name="css.ixml"> <entry name="css"/> </library> <library name="iri.ixml"> <entry name="iri"/> <entry name="uri"/> <entry name="urn"/> </library> <library name="xpath.ixml"> <entry name="xpath"/> </library> </use>
The set of invoked libraries is collected, including libraries in turn invoked by those libraries.
If any invoked library contains a rule whose name is the same as a rule in another invoked library, one of the rules is renamed. If one of the pair is a rule invoked by the original invoking grammar, then the other is renamed; otherwise it is not defined which is renamed.
A rule is renamed by generating a new unique name, different from all other rules in the set of libraries and the invoking grammar:
All uses of the old name in the library grammar, and any of the other libraries that invoked that rule are replaced with the new name.
All processed libraries are concatenated with the invoking grammar.
+use expr from expr.ixml .
data: identity+. identity: id, -"=", expr, -#a. id: [L]+. {expr.ixml, has clashing rule for id} expr: id++op. id: [L; Nd]*. op: ["+-×÷"].
data: identity+. identity: id, "=", expr. id: [L]+. {expr.ixml, id is renamed} expr: id_++op. id_>id: [L; Nd]*. op: ["+-×÷"].
+use expr from expr.ixml .
data: identity+. identity: id, -"=", expr, -#a. id: [L]+. {expr.ixml, has clashing rule for id, but that is already a renaming} expr: id++op. id>ident: [L; Nd]*. op: ["+-×÷"].
data: identity+. identity: id, "=", expr. id: [L]+. {expr.ixml, id is renamed} expr: id_++op. id_>ident: [L; Nd]*. op: ["+-×÷"].
+use expr from expr.ixml; identity from id.ixml . rules: rule+. rule: identity, -"=", expr. {library expr.ixml} expr: operand++op. operand: id; number. id: [L], [L; Nd]*. op: ["+-×÷"]. number: ["0"-"9"]+. {library identity.ixml, has clash with id from expr.ixml} identity: id; id, -"[", number, -"]". id: "@", [L]+. number: digits, ".", digits. -digits: [Nd]+.
rules: rule+. rule: identity, -"=", expr. {library expr.ixml; nothing needs changing} expr: operand++op. operand: id; number. id: [L], [L; Nd]*. op: ["+-×÷"]. number: ["0"-"9"]+. {library identity.ixml; id and number clash with expr.ixml; these could have been renamed in expr.ixml} identity: id_; id_, -"[", number_, -"]". id_>id: -"@", [L]+. number_>number: digits, ".", digits. -digits: [Nd]+.
+use id from ident.ixml; expr from expr.ixml rules: rule+. rule: id, -"=", expr. {identity.ixml} id: [L]+. {expr.ixml} +use id, number from id.ixml. expr: operand++op. operand: id; number. op: ["+-×÷"]. {id.ixml} id: [L], [L; Nd]*. number: [Nd]+.
rules: rule+. rule: id, -"=", expr. {identity.ixml, id cannot be renamed since it is used by the invoking grammar} id: [L]+. {expr.ixml, id from id.ixml clashes with rule used by invoking grammar} expr: operand++op. operand: id_; number. op: ["+-×÷"]. {id.ixml id clashes with original invoking grammar} id_: [L], [L; Nd]*. number: [Nd]+.