ASTと格闘している。いやlexerか。
僭越ながら ASTは、タダじゃ作ってくれない。 - 設計と実装の狭間で。 を添削。
添削してもらったので、少し直してみた。
そろそろ2byte文字も使ってみたいな…とか思って直している最中に、致命的な事が判明。
とりあえず、出来たトコまで晒しておくます。
grammar TwoWaySQL; options { language = Java; output = AST; ASTLabelType = CommonTree; } tokens { BEGINNODE; IFNODE; EXPRESSIONNODE; ELSENODE; } @header { package twowaysql.grammar; } @lexer::header { package twowaysql.grammar; } twowaySQL : txt EOF; txt : (IDENT | comment | WS | LT)+ ; // $<comment comment : begincomment | ifcomment | blockcomment | linecomment ; blockcomment : C_ST (IDENT | LT)+ C_ED ; linecomment : C_LN (IDENT)+ (LT|EOF) ; 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 | C_LN ELSE expression? LT ) -> ^(EXPRESSIONNODE expression?) ; expression : (IDENT | LT)+ ; begincomment : C_ST BEGIN C_ED txt endcomment -> ^(BEGINNODE txt) ; endcomment : C_ST END C_ED ; // $> C_ST : '/*'; C_ED : '*/'; C_LN : '--'; BEGIN : WS* ('b'|'B')('e'|'E')('g'|'G')('i'|'I')('n'|'N') WS*; IF : WS* ('i'|'I') ('f'|'F') WS*; ELSE : WS* ('e'|'E')('l'|'L')('s'|'S')('e'|'E') WS*; END : WS* ('e'|'E')('n'|'N')('d'|'D') WS*; // $<Charactors LT : '\n' // Line feed. | '\r' // Carriage return. | '\u2028' // Line separator. | '\u2029' // Paragraph separator. ; WS : '\t' | '\v' | '\f' | ' ' | '\u00A0'; IDENT : WS* CHAR+ WS*; fragment CHAR : ~( '\u002a' | '\u002f' |// ダメなのだけ省いてみた。 LT | WS) ; // $>
このgrammarに、こんなテキストを食わせる。
ada.cec のしのし / 3 d/*aa hoge piro*/ ぎゃぼー /* BeGiN*/ /* If aa bb dd*/moge piro /*eLsE ccc*/ccc /* ElSe */ zzz /*eNd*/ -- moge うぼぁ zz /* EnD*/
まず、一行目の「/ 3」の部分が宇宙の彼方に消える。
まぁ、/と*をCHARで使えないとしているので、そんなもんかな…と。
んで、
fragment CHAR : ~(LT | WS) ;
と、してみる。すると、「 /* If」の所まで来てMismatchedTokenExceptionでしぬ。
「/* BeGiN*/」の部分は、通過しているけど、ASTが生成されていない。
ううむ…。