Thursday, October 22, 2009

One last go around

grammar SXML ;

options{ k=4; backtrack=true; memoize=true; }

import XMLLexer ;

xmlDocument
    : prolog element misc*
    ;

/*
prolog
    : misc* docType?  misc*
    ;   
*/   
   
prolog
    : misc*
    ;       
   
misc
    : comment
    | pi
    | pcData
    | docType
    | WS
    ;

// simple items   
comment : COMMENT ;
pi      : PI {System.out.println("found pi");};
cdata   : CDATA ;       
pcData  : PCDATA ;

docType
    : DOCTYPE_OPEN (WS Name)+ (WS ATTR_VAL)* WS? docTypeDef? WS? eoe=ELE_OPEN_END
        {System.out.println("found doctype:"+ $eoe );}
    ;
   
docTypeDef
    :    LBRACKET ( docTypeDefItem )* RBRACKET
    ;
   
docTypeDefItem
    : elementDecl
    | attListDecl
    | entityDecl
    | notationDecl
    | pi
    | comment         
    | WS
    | pcData
    ;

elementDecl
    : ELEMENT_OPEN WS Name WS elementDeclContent WS? ELE_OPEN_END
    ;
   
elementDeclContent
    : Name
    | mixedContent
    | childrenContent
    ;
   
mixedContent
    : LPAREN WS? mixedContentItem ( WS? PIPE WS? mixedContentItem )* WS? RPAREN childOper?
    ;
   
mixedContentItem
    : POUND Name
    | Name
    | PCT Name SEMI
    ;               
   
childrenContent
    : (choice | sequence ) childOper?
    ;   
   
choice
    : LPAREN WS? child ( WS? PIPE WS? child )+  WS? RPAREN
    ;   
   
sequence
    : LPAREN WS? child ( WS? COMMA WS? child )*  WS? RPAREN
    ;       
   
child
    : Name childOper?
    | PCT Name SEMI childOper?
    | choice childOper?
    | sequence childOper?
    ;   

childOper
    :    QUEST | STAR | PLUS
    ;
       

   
attListDecl
    : ATTLIST_OPEN WS Name (attListDef)* WS? ELE_OPEN_END
    ;
   
attListDef
    : WS Name WS attListType WS defaultDecl
    ;       
   
attListType
    : Name
    | Name WS LPAREN WS? Name (WS? PIPE WS? Name)* WS? RPAREN
    | LPAREN WS? Name (WS? PIPE WS? Name)* WS? RPAREN
    ;
   
defaultDecl
    : ATTR_VAL
    | POUND Name (WS ATTR_VAL)?
    ;
        
   
entityDecl
    : ENTITY_OPEN (WS PCT)? (WS Name)+ (WS ATTR_VAL)* (WS Name)* WS? ELE_OPEN_END
    ;
   
notationDecl
    : NOTATION_OPEN WS Name (ATTR_VAL WS)* WS? ELE_OPEN_END
    ;       


element : emptyElement
        | contentElement
        ;
       
contentElement
    : ELE_OPEN_START Name (WS (attribute WS?)* )? ELE_OPEN_END
        content
        ELE_CLOSE_START Name ELE_OPEN_END
    ;
   
emptyElement : ELE_OPEN_START Name (WS (attribute WS?)* )? ELE_EMPTY_END ;
       
attribute : Name WS? ATTR_EQ WS? ATTR_VAL ;       
   
       
content   
    : contentItem*
    ;
   
contentItem
    : element
    | cdata 
    | pi
    | comment
    | pcData
    | WS
    ;   


lexer grammar XMLLexer ;

options{ k=11; backtrack=true; }

// memoize=true; }

@members {

    boolean inTag     = false;
    boolean inDocType = false;
    boolean inDocEle  = false;
   
    public boolean inEle(){
        return inDocType || inDocEle || inTag ;
    }
   
    public void closeDocType(){
        if( inDocEle ){
            inDocEle = false ;
            return;
        }
       
        if( inDocType ){
            inDocType = false ;
            return ;
        }
    }

}



// processing instructions
PI : PI_OPEN ( options{greedy=false;}: . )* PI_CLOSE ;
PI_OPEN : 'PI_CLOSE : '?>' ;

// comments
COMMENT : COMMENT_OPEN ( options{greedy=false;}: . )* COMMENT_CLOSE ;
COMMENT_OPEN : '' ;

// cdata
CDATA : CDATA_OPEN ( options{greedy=false;} : . )*  CDATA_CLOSE ;
CDATA_OPEN : '' ;

// includes
INCLUDE : INCLUDE_OPEN ( options{greedy=false;} : . )*  CDATA_CLOSE ;
INCLUDE_OPEN : '
CARET : '^' ;   
   
// 005F   
UNDER_SCORE : '_' ;   

BACK_TICK :    '`' ;

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

// 007D
PIPE : '|' ;

// 007E
TILDE : '~' ;

LCURLY : '{' ;
RCURLY : '}' ;

UNICODE_MISC
    : '\u00A0'..'\uD7FF'
    | '\uE000'..'\uFFFD' ;
   
// [3]
// #x20 ' ' \u0020
// #xA '\n'  \u000A
// #xD '\r'  \u000D
// #x9 '\t' \u0009
// do not preserve whitespace {$channel=HIDDEN;}
WS
    : ( '\r' | '\n' | '\t' | ' ' )+
    ;
   
SINK
    : sc=. { System.out.println("found sink.  char:"+ $sc ); };   

No comments:

Post a Comment