ISO-XML |
Top Previous Next |
Auf dieser Seite werden ein paar Hinweise gegeben, wie der TextTransformer XML-Parser aus den Standard-Spezifikationen für XML abgeleitet ist. Wer an diesen Einzelheiten nicht interessiert ist kann ohne weiteres mit der nächsten Seite fortfahren.
Der XML-Standard wird ausführlich beschrieben unter
http://www.xml.com/axml/testaxml.htm
Zur Spezifikation von XML wird dabei eine Extended Backus-Naur Form (EBNF) Notation verwendet, die ebenfalls standardisiert ist ( siehe: http://www.cl.cam.ac.uk/~mgk25/iso-ebnf.html).
Die standardisierte EBNF-Notation ( ISO-EBNF ) ist glücklicherweise der des TextTransformers ähnlich, ist jedoch nicht für den praktischen Einsatz konzipiert. ISO-EBNF ist erstens sehr elementar, so dass es eine Unterscheidung von Token und Produktionen nicht gibt. Zweitens nimmt die Grammatik keine Rücksicht auf deterministische Erkennbarkeit, insbesondere ist sie nicht LL(1)-konform. Zur Umformung der XML-Grammatik sind daher drei Schritte erforderlich:
1. ein Import-Projekt (quick and dirty) ähnlich dem Projekt zum Import von Coco-Parsern, wodurch die ISO-EBNF-XML-Regeln als TextTransformer-Produktionen importiert werden können. 2. alle Produktionen, die lediglich Zeichenfolgen beschreiben, werden in Token umgewandelt (siehe Anmerkungen unten). 3. LL(1)-Konflikte werden aufgelöst, ähnlich wie für den E-Mail-Adressen-Parser beschrieben.
Ein weiters Problem besteht darin, dass XML-Dokumente prinzipiell Unicode unterstützen, was der TextTransformer zur Zeit noch nicht leistet. (Die Option zur Erzeugung von Parser-Code auf Wide-Zeichen Basis ist in Arbeit:). Die ersten 128 Zeichen des ASCII-Codes und des UTF-8 codierter Unicode sind jedoch identisch, so dass der XML-Parser des TextTransformers, trotz entsprechender Vereinfachung der Token-Definitionen, die überwiegende Zahl von XML-Dokumenten lesen kann.
Weitere Anmerkungen zur Umformung von ISO-EBNF:
In ISO-EBNF gibt es einen Operator, zu dem es in der Tetra-Syntax kein Pendant gibt:
A - B passt auf jeden String der zu A passt aber nicht zu B
Einfach ist die Übersetzung dieses Operators dann, wenn es sich bei A und B um Zeichen oder Zeichenklassen handelt, da sich dann A - B zu einer Gesamtemenge akzeptierter Zeichen zusammenfassen lässt. Handelt es sich bei A und B um Zeichenfolgen, so kann B entweder eine zulässige Alternative von A - B sein oder das Auftreten von B im Eingabetext bedeutet einen Syntaxfehler.
Beispiel: ISO-EBNF: CData ::= (Char* - (Char* ']]>' Char*)) CDSect ::= CDStart CData CDEnd CDEnd ::= ']]>' Tetra: CData ::= ( Char )* CDSect ::= CDStart CData CDEnd CDEnd ::= ']]>'
ISO-EBNF: PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l')) Tetra: Name | XML EXIT Tetra: XML ::= [Xx][Mm][Ll]
Sehr häufig werden im ISO-EBNF Zeichenklassen als Reihen von alternativen Zeichen beschrieben. Soweit möglich sollten diese zu einer mit '[' und ']' geklammeren Menge zusammengefasst werden, da die das Scannen des Textes dadurch erheblich beschleunigt wird.
Beispiel: ISO-EBNF: S ::= (#x20 | #x9 | #xD | #xA)+ Tetra: S ::= [ \t\r\n]+
Bei der Zeichenmenge S des gerade gegeben Beispiels kann noch ein Schritt weiter gegangen werden. Es ist genau die Menge der auszulassenden Zeichen. Diese wird in der ISO-EBNF nicht als solche spezifiziert. Vielmehr wird jede Stelle der Grammtik explizit angegeben, an denen S vorkommen kann oder muss. Dadurch wird zum einen die Grammatik unübersichtlich und zum anderen entstehen dadurch für LL(1)-Parser Konflikte.
Beispiel: XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>' EncodingDecl ::= S 'encoding' ... SDDecl ::= S 'standalone' Eq ...
Nach dem Erkennen von VersionInfo gibt es gleich drei Möglichkeiten, mit S fortzufahren. Wird S hingegen als Menge der auszulassender Zeichen definiert, ist die Regel LL(1). Auf VersionInfo folgt: 'encoding' | 'standalone' | '?>'
Wird S als Menge der auszulassenden Zeichen definiert, dann sollten allerdings Zeichenketten zwischen denen S nicht vorkommen kann zu Token zusammengefasst werden:
Beispiel: ISO-EBNF: EntityRef ::= "&" Name ";" Tetra: EntityRef ::= &{Name}; wobei {Name} ein Makro für die Zeichenmenge Name ist.
Als Problem bleiben Leerzeichen, die von der ISO-EBNF-Spezifikation an bestimmten Positionen gefordert werden. Es könnten in Tetra Token, auf die ein Leerzeichen folgen muss gesondert definiert werden. Damit wäre allerdings die Eleganz, die durch die Verwendung der auszulasenden Zeichen gewonnen wurde teilweise wieder verloren. Da der Beispielsparser nicht zur Verifikation der XML-Konformität, sondern dem Lesen und Verarbeiten von XML-Dokumenten dienen soll, muss man sich um diesen Punkt kein Kopfzerbrechen machen.
|
Diese Seite gehört zur TextTransformer Dokumentation |
Home Inhalt English |