バインド変数コメントは、本家と仕様を変えてみた。
こんな感じに、#をブロックコメントの開始の後に付けとくとバインド変数コメントになる。
/*# hogehoge.fugagua*/dummy
grammar TwoWaySQL; options { language = Java; output = AST; ASTLabelType = CommonTree; } tokens { BEGINNODE; IFNODE; EXPRESSIONNODE; ELSENODE; ELSEIFNODE; BINDNODE; INBINDNODE; } @header { package twowaysql.grammar; } @lexer::header { package twowaysql.grammar; } @lexer::members { boolean inComment = false; boolean inLineComment = false; } twowaySQL : txt EOF; txt : (comment | inbind | charactors)+ ; charactors : (IDENT| SYMBOLS | QUOTED | SYM_N | SYM_C | SYM_LP | SYM_RP)+ ; // $<comment comment : begincomment | ifcomment | bindcomment | blockcomment | linecomment ; blockcomment : C_ST charactors C_ED; linecomment : C_LN_ST charactors C_LN_ED; ifcomment : (C_ST IF expression C_ED txt elseifnode* elsenode? endcomment) -> ^(IFNODE expression txt elseifnode* elsenode? ) ; elseifnode : elseifcomment txt -> ^(ELSEIFNODE elseifcomment txt); elsenode : elsecomment txt -> ^(ELSENODE txt); elseifcomment : (C_ST ELSEIF expression C_ED | C_LN_ST ELSEIF expression C_LN_ED) -> expression; elsecomment : (C_ST ELSE C_ED | C_LN_ST ELSE C_LN_ED) ; expression : charactors -> ^(EXPRESSIONNODE charactors); begincomment : ((C_ST BEGIN C_ED | C_LN_ST BEGIN C_LN_ED) txt endcomment) -> ^(BEGINNODE txt); endcomment : C_ST END C_ED | C_LN_ST END C_LN_ED; bindcomment : (C_ST SYM_N expression C_ED charactors+) -> ^(BINDNODE expression); inbind : IN C_ST SYM_N expression C_ED SYM_LP inbindchars (SYM_C inbindchars+)* SYM_RP -> ^(INBINDNODE IN expression); inbindchars : (IDENT| SYMBOLS | SYM_C | QUOTED)+; // $> SYMBOLS : '*' | '/' | '-'; SYM_LP : '('; SYM_RP : ')'; SYM_C : ','; SYM_N : '#'; QUOTED : SYM_Q ~(SYM_Q)+ SYM_Q; fragment SYM_Q : '\u0027' | '"'; C_ST : {!inComment}? '/*' { inComment = true; }; C_ED : {inComment}? '*/' { inComment = false; }; C_LN_ST : {!inComment}? '--' { inLineComment = true; inComment = true; }; C_LN_ED : {inLineComment}? ( LN_R LN_N | LN_R | LN_N | EOF ) { inLineComment = false; inComment = false; }; // $<Keywords BEGIN : ('b'|'B')('e'|'E')('g'|'G')('i'|'I')('n'|'N'); IF : ('i'|'I')('f'|'F'); ELSE : ('e'|'E')('l'|'L')('s'|'S')('e'|'E'); ELSEIF : ELSE IF; END : ('e'|'E')('n'|'N')('d'|'D'); IN : {!inComment}? ('i'|'I')('n'|'N'); // $> IDENT : CHAR+; fragment WS : '\t' | ' '; fragment LN_R : '\r'; fragment LN_N : '\n'; fragment CHAR : ~(SYMBOLS | SYM_Q | SYM_N | SYM_LP | SYM_RP | SYM_C | LN_R | LN_N | WS); LT : {!inLineComment}? (LN_R | LN_N)+ { $channel = HIDDEN; }; WHITE_SPACES : (WS)+ { $channel = HIDDEN; };
こんなテキストを食わせているけど、そこそこイイ感じ。
ada.cec のしのし / 30 d/*aa hoge,( piro*/ vvぎゃぼー -- BeGiN /* If aa - bb dd*/moge piro /*eLsEIF ccc + 44 '*/' */cccd -- elSEif fuga < '0' dfdze /*# dfd*/ vvvvvdfded -- ElSe zzz "-- fugafuga" iN/* # hoge In(aa,bbb)*/('hoge',40) -- eNd -- moge うぼぁ zz /* EnD*/
そろそろ、文法定義も一通り出来たし、エラー処理を書き始めようかしらん…