Tuesday, September 22, 2009

Antlr XML Grammar

Fixed an issue with quotes inside a comment or cdata section

grammar XML ;

options {
    backtrack=true;
}
// 1
xmlDocument
    : prolog element misc*
    ;
   
prolog
    : xmlDecl misc* (doctypedecl  misc*)?
    ;
   
// [27]
misc
    : comment
    | pi
    ;    

// 2.5 Comments
// [15] - should a comment be a parser rule?
/*
comment
    : CommentOpen commentContent* CommentClose
    ;
   
commentContent
    : ~CommentClose
    ;   
*/
   
comment
    : COMMENT
    ;
   
COMMENT
    : CommentOpen ( options{greedy=false;}: . )* CommentClose   
    ;
   
// 2.8   
// Document Type Definition
// [28]
doctypedecl : DocTypeOpen Name (externalID)? ( LBRACKET intSubset RBRACKET )? GT ;


// [28b]      

intSubset : (markupdecl | declSep)* ;

// [29]
markupdecl
    : elementdecl
    | attlistDecl
    | entityDecl
    | notationDecl
    | pi
    | comment    
    ;
   
// 2.6 Processing Instructions
// [16]
pi
    : PIOpen PITarget PIData* PIClose
    ;
   
// External Subset
// [30]
extSubset : textDecl? extSubsetDecl ;

// [31]
extSubsetDecl : ( markupdecl | conditionalSect | declSep)*     ;


// 3 .0
// Element
// [39]
element : emptyElemTag
        | sTag content eTag
        ;


// Content of Elements
// [43]
content   
    : contentItem*
    ;
   
contentItem
    : element
    | reference
    | CDSect
    | pi
    | comment
    | charData
    ;   
   
// 2.4 Character Data and Markup
// [14]
charData
    : charDataItem+
    ;


charDataItem
    : ~( LT
    | AMP
    | CDataEnd
    | CDataStart
    | CommentOpen
    | ETagOpen
    | ElementDeclOpen
    | AttListDeclOpen
    | EntityRef
    | NotationDeclOpen
    | PIOpen
    | STagOpen )
    ;   
   

// 3.2
// Element Type Declaration
// [45]
elementdecl : ElementDeclOpen Name contentspec GT ;



// [46]
contentspec
    : Empty
    | Any
    | mixed
    | children
    ;

// 3.2.1   
// Element-content Models
// [47]
children
    : ( choice | seq ) modifier?
    ;

// [48]   
cp
    : (Name | choice | seq) modifier?
    ;
   
// [49]
choice
    : LPAREN cp ( PIPE cp )+ RPAREN
    ;
   
// [50]
seq   
    : LPAREN cp ( COMMA cp )* RPAREN
    ;
   
modifier : ( QUEST | STAR | PLUS ) ;
   
   
// 3.2.2
// Mixed-content Declaration
// [51]
mixed : LPAREN PCData ( PIPE Name )*  RPAREN
    | LPAREN PCData RPAREN
    ;
   

// 3.3   
// Attribute-list Declaration
// [52]
attlistDecl : AttListDeclOpen Name (attDef)* GT ;

// [53]
attDef : Name attType defaultDecl ;
               
               
// 3.3.1
// Attribute Types
// [54]
attType : stringType | tokenizedType | enumeratedType ;

// [55]
stringType : CDataType ;



// [56]
tokenizedType
    : ID   
    | IDREF
    | IDREFS   
    | ENTITY   
    | ENTITIES   
    | NMTOKEN   
    | NMTOKENS
    ;
   
   
   
// Enumerated Attribute Types
// [57]
enumeratedType
    : notationType
    | enumeration
    ;
   
// [58]
notationType
    : NOTATION LPAREN Name ( PIPE Name)* RPAREN
    ;

enumeration
    : LPAREN (Name) ( PIPE (Name) )*  RPAREN
    ;
   
// 3.3.2
// Attribute Defaults
// [60]
defaultDecl
    : Required
    | Implied
    | (Fixed)? StringLiteral
    ;

   
                               
                               
// 3.4                               
// Conditional Section
// [61]
conditionalSect
    : includeSect
    | ignoreSect
    ;
   
// [62]
includeSect
    : Cond_Open Include LBRACKET extSubsetDecl CDataEnd
    ;
   
// [63]
ignoreSect
    : Cond_Open IGNORE LBRACKET ignoreSectContents* CDataEnd 
    ;
   
ignoreSectContents
    : IgnoreItem ( Cond_Open ignoreSectContents CDataEnd IgnoreItem)*
    ;
   


// 4.3
// Text Declaration
// [77]
textDecl : XMLDeclOpen versionInfo? encodingDecl PIClose ;

// Well-Formed External Parsed Entity
// [78]
extParsedEnt
    : textDecl? content
    ;
   
// Encoding Declaration
// [80]
encodingDecl : Encoding EQ StringLiteral ;



// 4.7
// [82]
notationDecl
    : NotationDeclOpen Name  (externalID | publicID) GT
    ;

// [83]
publicID
    : PublicToken StringLiteral
    ;
   

// 4.2.2 External Entities
// [75]
externalID
    : SystemToken StringLiteral
    | PublicToken StringLiteral StringLiteral
    ;
   
// [76]
nDataDecl
    : NData Name
    ;


// 4.2
// Entity Declaration
// [70]
entityDecl
    : EntityDeclOpen PCT? Name entityDef GT
    ;
   
// [73]
entityDef
    : StringLiteral
    | externalID nDataDecl?
    ;
   

   
   
// 4.2   
// Entity Reference
// [67]      
reference   
    : EntityRef
    | CharRef
    ;
   

// 3.1       
// Start-tag

// [40]
sTag : STagOpen (attribute|versionInfo)* GT ;



// [41]
attribute : Name EQ StringLiteral ;

// End-tag
//[42]
eTag : ETagOpen Name GT ;


// Tags for Empty Elements
// [44]
emptyElemTag : STagOpen (attribute)*  ETagClose ;


   

// 2.9
// Standalone Document Declaration
// [32]
sdDecl : Standalone EQ StringLiteral ;
   

// [28a]
declSep : PEReference ;

// [23]
xmlDecl    : XMLDeclOpen versionInfo (encodingDecl)? (sdDecl)? PIClose ;



// [24]
versionInfo : Version EQ StringLiteral ;


// LEXER



// 4.1
// Character Reference
// [66]
CharRef   
    : '&#' DIGIT+ ';'
    | '&#x' ( DIGIT | 'a'..'f' | 'A'..'F' )+ ';'   
    ;
   
   
// [68]
EntityRef : '&' Name ';' ;

// [69]
PEReference : '%' Name ';' ;   



STagOpen : LT Name ;



ETagOpen : '
   
ETagClose :    '/>' ;   


DocTypeOpen : '


XMLDeclOpen : '
Version : 'version' ;
   
// [65]
fragment IgnoreItem
    : ~( Cond_Open | CDataEnd )
    ;
   
Cond_Open : '// move to Parser?
// CDSect : CDataStart  CData*  CDataEnd ;

CDSect : CDataStart  ( options{greedy=false;} : . )*  CDataEnd ;

// [19]
CDataStart : '// - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
fragment PITarget : Name  ;


PIOpen : 'PIClose : '?>' ;

   

CommentOpen : '' ;



   
// Key words and long tokens

   
CDataEnd : ']]>' ;

ElementDeclOpen : '
// 0028
fragment LPAREN : '(';

// 0029   
fragment RPAREN : ')' ;

// 002A
STAR :    '*' ;

// 002B
fragment PLUS : '+';

// 002C
fragment COMMA : ',';
   
// 002D   
MINUS : '-' ;

// 002E
DOT : '.' ;

// 002F
FWD_SLASH : '/' ;

// 0030..0039
DIGIT : '0'..'9';

// 003A   
fragment COLON : ':' ;   

// 003B
fragment SEMI : ';' ;

// 003C
fragment LT : '<' ;

// 003D
EQ : '=' ;

// 003E
GT : '>' ;   

// 003F
fragment QUEST : '?' ;

// 0040
fragment AT : '@' ;

// 0041..005A
fragment UPPER : 'A'..'Z' ;

// 005B
fragment LBRACKET : '[' ;

// 005C
fragment BACK_SLASH  :    '\\';

// 005D
fragment RBRACKET :    ']';

   
// 005F   
fragment UNDER_SCORE :    '_' ;   


//     0061..007A
fragment LOWER : 'a'..'z' ;

// 007D
fragment PIPE : '|' ;

// [3]
// #x20 ' ' \u0020
// #xA '\n'  \u000A
// #xD '\r'  \u000D
// #x9 '\t' \u0009
WS
    : ( '\r' | '\n' | '\t' | ' ' )+ {$channel=HIDDEN;}
    ;

No comments:

Post a Comment