Figure 1: Simple XML parser grammar represented in EBNF form

document     ::= XMLDecl? Misc* element Misc*
XMLDecl      ::= '<?xml' VersionInfo EncodingDecl? S? '?>'
     
VersionInfo  ::= S 'version' Eq 
                 (' VersionNum ' | " VersionNum ")
Eq           ::= S? '=' S?
VersionNum   ::= ([a-zA-Z0-9_.:] | '-')+
     
EncodingDecl ::=  S 'encoding' Eq 
                  ('"' EncName '"' |  "'" EncName "'")
EncName      ::=  [A-Za-z] ([A-Za-z0-9._] | '-')*
     
S            ::= (#x20 | #x9 | #xD | #xA)+ 
Misc         ::= Comment | S
Comment      ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* 
                 '-->'
     
Name         ::=  (Letter | '_' | ':') (NameChar)* 
NameChar     ::=  Letter | Digit | '.' | '-' | '_' | ':' |
                  CombiningChar | Extender
     
Reference    ::=  EntityRef | CharRef 
EntityRef    ::=  '&' Name ';'
CharRef      ::=  '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'
     
Attribute    ::=  Name Eq AttValue
AttValue     ::= '"' ([^<&"] | Reference)* '"'  |
                 "'" ([^<&'] | Reference)* "'"
     
CDSect       ::=  '<![CDATA[' CData ']]>' 
CData        ::=  (Char* - (Char* ']]>' Char*))
     
element      ::= EmptyElemTag | STag content ETag 
STag         ::=  '<' Name (S Attribute)* S? '>'  
ETag         ::=  '</' Name S? '>'
EmptyElemTag ::=  '<' Name (S Attribute)* S? '/>' 
CharData     ::=  [^<&]* - ([^<&]* ']]>' [^<&]*) 
content      ::=  (element | CharData | Reference |
                   CDSect | Comment)*