2

再解析されて再タグ付けされた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)*形式であるため)失敗するのはなぜですか?

4

1 に答える 1

1

入力を解析すると:

config HAVE_DEBUG_RAM_SETUP
def_bool n

文法から生成されたパーサーを使用すると、次の解析ツリーが得られます。

ここに画像の説明を入力してください

ですから、ここでは問題はありません。私の推測では、ANTLRWorksのインタプリタを使用していると思います。使用しないでください。バギーです。常に独自のクラスで文法をテストするか、ANTLWorksのデバッガーを使用してください(CTRL+Dを押して起動します)。デバッガーはチャームのように機能します(パッケージ宣言なし)。上に投稿した画像は、デバッガーからのエクスポートです。

編集

デバッガーが機能しない場合は、パッケージ宣言を(一時的に)削除してみてください(パーサーではなく、レクサーのパッケージのみを宣言していることに注意してください。ただし、最小限の文法を投稿したことが原因である可能性があります)。デバッガーが接続するポート番号を変更してみることもできます。ポートがすでに使用されている可能性があります(File -> Preferences -> Debugger-tabを参照)。

于 2012-09-20T19:09:44.600 に答える