JavaCC って LookAhead 内は LookAhead を無視するの?
kuzha で x++ って入力するとエラーが出ていた件を詳細に調べてみた。
まず、パーサの基幹部はこんな定義。
Statement CompilationUnit():{ Token start; Statement stt; Expression expr; }{ { jj_ntk(); start = token.next; } ( LOOKAHEAD(Expression() <EOF>) expr = Expression() <EOF> { stt = new ReturnStatement(expr); } | stt = Statements() <EOF> ) { return p(start, getToken(0), stt); } }
Expression()
Expression PostExpression():{ Expression expr; PostMessage msg; PostArgument args; }{ LOOKAHEAD((<ID>|"<!>")(":"|"@")) msg = PostingMessage() { return new PostSpecialExpression(SymbolName.LOCAL, msg); } | expr = PrimitiveExpression() [ LOOKAHEAD(PostingMessageLA()) msg = PostingMessage() { expr = new PostExpression(expr, msg); } ] { return expr; } }
LOOKAHEAD(Expression()
Call: CascadeExpression(LOOKING AHEAD...) Call: PostExpression(LOOKING AHEAD...) Call: PostingMessage(LOOKING AHEAD...) Visited token: <<ID>: "x" at line 1 column 1>; Expected token: <<ID>> Call: CallArgument(LOOKING AHEAD...) Call: ThisCallArgument(LOOKING AHEAD...) Visited token: <"++" at line 1 column 2>; Expected token: <"@"> Return: ThisCallArgument(LOOKAHEAD FAILED) Call: SimpleCallArguments(LOOKING AHEAD...) Visited token: <"++" at line 1 column 2>; Expected token: <":"> Return: SimpleCallArguments(LOOKAHEAD FAILED) Return: CallArgument(LOOKAHEAD SUCCEEDED) Return: PostingMessage(LOOKAHEAD SUCCEEDED) // 本当はここで成功してはならない Return: PostExpression(LOOKAHEAD SUCCEEDED) Visited token: <"++" at line 1 column 2>; Expected token: <","> Return: CascadeExpression(LOOKAHEAD SUCCEEDED)
さて、どうやって解決しようかな。
要は PostingMessage でパースできる内容と LOOKAHAED に書かれた実態が食い違ってるから生じる問題だし、PostingMessage の内容を若干修正することで解決してみた。