JavaCC の LOOKAHEAD にまつわる不思議な挙動
JavaCC って LookAhead 内は LookAhead を無視するの? - SiroKuro Page に関して、実証コードができました。JavaCC4.0 で確認してます。
PARSER_BEGIN(Test) import java.io.*; public class Test { public static void main(String[] args) throws Exception { new Test(new StringReader("ac")).foo(); } } PARSER_END(Test) TOKEN : { "a" | "b" | "c" | "d" } void foo():{ }{ LOOKAHEAD(bar() <EOF>) bar() <EOF> // ※ | "d" <EOF> } void bar():{ }{ LOOKAHEAD("a" "b") "a" ["b"] | "a" "c" }
動作は以下の流れ。
- 入力は "ac" の二文字。トークンは "a" "c"
の順。 - foo() が呼ばれる
- LOOKAHEAD(bar()
) を実行 - bar() を先読み開始
- "a" ["b"] を解釈し、トークン "a" を先読み消費
- bar() の先読み成功
- 残りは "c"
だが、次に来るべきは なので先読み失敗 - LOOKAHEAD(bar()
) の先読みに失敗 - "d" をパースしようとして失敗
- 全体のパースが失敗する
ちなみに※印の行の LOOKAHEAD を削除すると、正常にパースできるようになる。ちょっと躓きやすい挙動だなぁ。JavaCC のマニュアル読めば書いてあるのかな。まあ、要は実態にそぐわない LOOKAHEAD("a" "b") なんて書くのが悪いんですけどね( ´ー`)y-~~