function normalizeClauseName(sClauseName) {
return replaceString(".", "_", replaceString("-", "_", sClauseName));
}
XML_DOCUMENT ::=
#ignore(XML)
[
"<?xml" #continue
"version" '=' #readCString
["encoding" #continue '=' #readCString]?
"?>"
]?
[
"<!DOCTYPE" #continue
IDENTIFIER EXTERNAL_DOCTYPE
[#readCString]* '>'
]?
ELEMENT(this)
#empty;
ANY_ATTRIBUTES(myCurrentNode : node) ::=
[
IDENTIFIER:sAttribute
#continue '='
#readCString:sValue
=> insert #evaluateVariable("myCurrentNode." + normalizeClauseName(sAttribute)) = sValue;
]*;
ELEMENT(myCurrentNode : node) ::=
'<' IDENTIFIER:sOpenElement
#continue
=> local sVariable = "myCurrentNode." + normalizeClauseName(sOpenElement);
=> pushItem #evaluateVariable(sVariable);
=> localref myElement = #evaluateVariable(sVariable + "#back");
ANY_ATTRIBUTES(myElement)
[
"/>"
|
'>'
[
[ELEMENT(myElement)]+
|
PCDATA_LITERAL:myElement
]
"</" IDENTIFIER:sCloseElement
=> if sOpenElement != sCloseElement error("'</" + sCloseElement + ">' found to close '<" + sOpenElement + ">'");
'>'
];
PCDATA_LITERAL ::= #!ignore #continue [ESC|~'<']*:PCDATA_LITERAL;
EXTERNAL_DOCTYPE ::= "PUBLIC" #continue #readCString #readCString | "SYSTEM" #continue #readCString;
IDENTIFIER : value ::=
#!ignore #readIdentifier:IDENTIFIER
[['-' | '.'] #readIdentifier]*:sIdentifier
=> set IDENTIFIER += sIdentifier;
;
ESC ::= #!ignore '\\' ['n' | 't' | 'v' | 'b' | 'r' | 'f' | 'a' | '\\' | '?' | '\'' | '"' | HEX | OCTAL];