ドラゴンブックの一例をANTLRで再現しようとしました:
grammar left_recursion_2;
options {
language = java;
}
program : 'begin'
stmt+
'end'
;
stmt : unmatched_stmt
| matched_stmt
;
matched_stmt : 'if' expr 'then' matched_stmt 'else' matched_stmt
| other
;
unmatched_stmt : 'if' expr 'then' stmt
| 'if' expr 'then' matched_stmt 'else' unmatched_stmt
;
expr : 'expression'
;
other : 'other'
;
問題はエラー 211 です。
[致命的] ルール unmatched_stmt は、alts 1、2 から到達可能な再帰的なルール呼び出しにより、非 LL(*) 決定を持っています。左因数分解するか、構文述語を使用するか、backtrack=true オプションを使用して解決します。
バックトラッキングをオンにすることはできますが、バックトラッキングなしで解決する方法を知りたいです。また、ここで述語がどのように役立つかわかりません。私はこれを読みました:
http://www.antlr.org/wiki/display/ANTLR3/How+to+remove+global+backtracking+from+your+grammar
しかし、まだわかりません。
バックトラックせずに機能するように、どのように文法を書き直しますか?
前もって感謝します!
編集:それまでの間、それは不可能であるという結論に達しました。LL(*) は DFA を使用して先読みするため、適用するルール (「if-else」ルールまたは「if only」ルール) を決定する機会はありません。しかし、バックトラッキングや AST の後処理を使用するよりも、それに対処する方法を誰かが知っている場合は、私に知らせてください。