空白のスキップとクォート出来る様にしてみた。
■[ANTLR] 空白文字のスキップCommentsAdd Starwarufuzaketaichi
引き続き、ASTは、タダじゃ作ってくれない。 - 設計と実装の狭間で。を添削。
予想以上に大変。
らしいのだけど、せっせとコピペしたので、それなりに楽勝。
しかし、それでは芸がないので、クォート処理をレキサーでやってみた。
grammar TwoWaySQL; options { language = Java; output = AST; ASTLabelType = CommonTree; } tokens { BEGINNODE; IFNODE; EXPRESSIONNODE; ELSENODE; } @header { package twowaysql.grammar; } @lexer::header { package twowaysql.grammar; } @lexer::members { boolean inComment = false; boolean inLineComment = false; } twowaySQL : txt EOF; txt : (comment | charactors)+ ; charactors : (IDENT| SYM_A| SYM_S | SYM_H | QUOTED)+ ; // $<comment comment : begincomment | ifcomment | blockcomment | linecomment ; blockcomment : C_ST (charactors)+ C_ED ; linecomment : C_LN_ST (charactors)+ C_LN_ED ; ifcomment : C_ST IF expression C_ED txt (elsecomment txt)* endcomment -> ^(IFNODE ^(EXPRESSIONNODE expression) txt ^(ELSENODE elsecomment txt)*) ; elsecomment : (C_ST ELSE expression? C_ED -> ^(EXPRESSIONNODE expression?) |C_LN_ST ELSE lineexpression? C_LN_ED -> ^(EXPRESSIONNODE lineexpression?) ) ; expression : (charactors)+ ; lineexpression : (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 ; // $> 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; }; QUOTED :SYM_Q ~(SYM_Q)+ SYM_Q; LT : {!inLineComment}? (LN_R | LN_N)+ { $channel = HIDDEN; }; WS : ('\t' | '\v' | '\f' | ' ' | '\u00A0')+ { $channel = HIDDEN; }; SYM_A : '*'; SYM_S : '/'; SYM_H : '-'; SYM_Q : '\u0027'; 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'); END : ('e'|'E')('n'|'N')('d'|'D'); IDENT : CHAR+; fragment LN_R : '\r'; fragment LN_N : '\n'; CHAR : ~(SYM_A | SYM_S | SYM_H | SYM_Q | LN_R | LN_N | '\t' | '\v' | '\f' | ' ' | '\u00A0');
こんなテキストを食わせてるます。
ada.cec のしのし / 3 d/*aa hoge piro*/ ぎゃぼー -- BeGiN /* If aa - bb dd*/moge piro /*eLsE ccc + 44 '*/' */cccd -- elSE fuga < '0' dfdze -- ElSe zzz '-- fugafuga' -- eNd -- moge うぼぁ zz /* EnD*/
ポイントは、
/*eLsE ccc + 44 '*/' */
で、コメントが変な風に中断したり、
'-- fugafuga'
がコメントノードにならずテキストノードになる事ダス。
タダね、これだと、実は余りうまくない。
SQL内の空白は、最悪消えても良いのだけど、
コメント内の空白文字は、消えてしまっては困るのです。
何故なら、IFコメントとかのexpression部分は外部の式言語にそのまま食わせるから。