再解析されて再タグ付けされたkconfigファイル(いくつかのあいまいさを解決するために再タグ付けされた)のANTLR文法を書き込もうとしています。文法の簡略版は次のとおりです。
grammar FailureExample;
options {
language = Java;
}
@lexer::header {
package parse.failure.example;
}
reload
: configStatement*
EOF
;
configStatement
: CONFIG IDENT
configOptions
;
configOptions
: (type
| defConfigStatement
| dependsOnStatement
| helpStatement
| rangeStatement
| defaultStatement
| selectStatement
| visibleIfStatement
| prompt
)*
;
type : FAKE1;
dependsOnStatement: FAKE2;
helpStatement: FAKE3;
rangeStatement: FAKE4;
defaultStatement: FAKE5;
selectStatement:FAKE6;
visibleIfStatement:FAKE7;
prompt:FAKE8;
defConfigStatement
: defConfigType expression
;
defConfigType
: DEF_BOOL
;
//expression parsing
primative
: IDENT
| L_PAREN expression R_PAREN
;
negationExpression
: NOT* primative
;
orExpression
: negationExpression (OR negationExpression)*
;
andExpression
: orExpression (AND orExpression)*
;
unequalExpression
: andExpression (NOT_EQUAL andExpression)?
;
equalExpression
: unequalExpression (EQUAL unequalExpression)?
;
expression
: equalExpression (BECOMES equalExpression)?
;
DEF_BOOL: 'def_bool';
CONFIG : 'config';
COMMENT : '#' .* ('\n'|'\r') {$channel = HIDDEN;};
AND : '&&';
OR : '||';
NOT : '!';
L_PAREN : '(';
R_PAREN : ')';
BECOMES : '::=';
EQUAL : '=';
NOT_EQUAL : '!=';
FAKE1 : 'fake1';
FAKE2: 'fake2';
FAKE3: 'fake3';
FAKE4: 'fake4';
FAKE5: 'fake5';
FAKE6: 'fake6';
FAKE7: 'fake7';
FAKE8: 'fake8';
IDENT : (LETTER | DIGIT | '_')*;
WS : ( ' '
| '\t'
| '\r'
| '\n'
) {$channel=HIDDEN;}
;
fragment LETTER : ('a'..'z' | 'A'..'Z') ;
fragment DIGIT : '0'..'9';
入力あり:
config HAVE_DEBUG_RAM_SETUP
def_bool n
2行目だけを解析するようにantlrworksを設定すると(最初の行をコメントアウト)、次の適切な式で適切なdefConfigStatementトークンが発行されます。ただし、configOptionsルールまたはconfigStatementルール(最初の行はコメントなし)を実行すると、configOptionsの結果が空になり、NoViableAlt例外がスローされます。
この動作の原因は何ですか?defConfigStatementルールが正確で正しく解析できることは知っていますが、別のルールの潜在的なオプションとして追加されるとすぐに失敗します。競合するルールがないことはわかっています。DEF_BOOLルールとDEF_TRISTATEルールをレクサールールのリストの一番上にしたので、他のレクサールールよりも優先されます。
/編集後に追加/問題をさらに複雑にするために、configOptionsルールでdefConfigStatementの選択肢を移動すると、機能しますが、他のルールは失敗します。
編集:完全で単純化された文法を使用します。
要するに、ルールがそれ自体で機能するのに、configOptionsにある場合(特にconfigOptionsが(A | B | C)*形式であるため)失敗するのはなぜですか?