文法がわからん…
こんな感じ?SQL部分はかなりいい加減ですが
grammar Way2; options { output = AST; ASTLabelType=CommonTree; } tokens { PROGRAM; UNSTRUCTURED; BIND_LITERAL; BIND_LIST; REPLACE; LIST; THEN; QUALIFIED; } @lexer::members { private boolean inBlockComment = false; private boolean inLineComment = false; } program : sql_fragment* EOF -> ^(PROGRAM sql_fragment*) ; // fragments sql_fragment : unstructured | list | bind | replace | if_block | begin_block ; unstructured : ~( COMMENT_START | LIST_START | LIST_END | COMMENT_END ) ; bind : bind_comment ( literal -> ^(BIND_LITERAL bind_comment literal) | list -> ^(BIND_LIST bind_comment list) ) ; replace : replace_comment literal -> ^(REPLACE replace_comment literal) ; list : LIST_START sql_fragment* LIST_END -> ^(LIST sql_fragment*) ; if_block : if_comment sql_fragment* elseif_comment* else_comment? end_comment -> ^(IF if_comment ^(THEN sql_fragment*) elseif_comment* else_comment) ; begin_block : begin_comment sql_fragment* end_comment -> ^(BEGIN sql_fragment*) ; // expressions expression : literal ; literal : LITERAL ; qualified : IDENT ( DOT IDENT )* -> ^(QUALIFIED IDENT*) ; //// structured comments replace_comment : COMMENT_START DOLLER qualified COMMENT_END -> qualified ; bind_comment : COMMENT_START IDENT COMMENT_END -> IDENT ; if_comment : COMMENT_START IF expression COMMENT_END -> ^(IF expression) ; elseif_comment : COMMENT_START ELSEIF expression sql_fragment* COMMENT_END -> ^(ELSEIF expression ^(THEN sql_fragment*)) ; else_comment : COMMENT_START ELSE sql_fragment* COMMENT_END -> ^(ELSE sql_fragment*) ; begin_comment : COMMENT_START BEGIN COMMENT_END -> ^(BEGIN) ; end_comment : COMMENT_START END COMMENT_END -> ^(END) ; // reserved.. IF : 'IF' ; ELSEIF : 'ELSEIF' ; ELSE : 'ELSE' ; BEGIN : 'BEGIN' ; END : 'END' ; LIST_START : '(' ; LIST_END : ')' ; DOLLER : '$' ; DOT : '.' ; COMMA : ',' ; LITERAL : ( '0'..'9' )+ ; IDENT : ( 'A'..'Z' | 'a'..'z' | '_' ) ( 'A'..'Z' | 'a'..'z' | '_' | '0'..'9' )* ; COMMENT_START : {!inBlockComment}? '/*' { inBlockComment = true; } | {!inBlockComment && !inLineComment}? '--' { inLineComment = true; } ; COMMENT_END : {inLineComment}? ( LINE_BREAK | EOF ) { inBlockComment = false; inLineComment = false; } | {inBlockComment}? '*/' { inBlockComment = false; } ; WHITESPACE : ( ' ' | '\t' )+ { $channel = HIDDEN; } | { !inLineComment }? LINE_BREAK+ { $channel = HIDDEN; } ; fragment LINE_BREAK : '\r\n' | '\r' | '\n' ;
/* IF 1 */ /* a */1 -- ELSEIF 2 /* $a.b.c */2 -- ELSEIF 3 /* d */ 3 -- ELSEIF 4 IN /* hogehoge */(a, b, c) -- ELSE 999 /* END */