A Proposal for an ixml Preprocessor

Steven Pemberton

Introduction

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.

Example of use

+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.

Syntax

use: -"+", s, -"use", rs, library++(-";", s), -".".
library: rulenames, -"from", rs, name, s.
-rulenames: entry++(-",", s).
entry: name, s.

Restrictions:

Example

+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>

Processing

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.

Example

+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: ["+-×÷"].

Result

data: identity+.
identity: id, "=", expr.
id: [L]+.

{expr.ixml, id is renamed}
expr: id_++op.
id_>id: [L; Nd]*.
op: ["+-×÷"].

Example

+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: ["+-×÷"].

Result

data: identity+.
identity: id, "=", expr.
id: [L]+.

{expr.ixml, id is renamed}
expr: id_++op.
id_>ident: [L; Nd]*.
op: ["+-×÷"].

Example

+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]+.

Result

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]+.

Example

+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]+.

Result

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]+.