1

であいまいさを処理する方法を解決しようとしていますANTLR。識別子またはサイズ プレフィックス付きの識別子を正しく解析する必要があります。最初にこのバグのある文法にたどり着きました

grammar PrefixProblem;
options       
{   
    language = Java;
}
goal: (size_prefix ':')? id;
size_prefix: B;
id: LETTER+;
LETTER: 'A'..'Z' ;
B: 'B';
WSFULL:(' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;};

prefix とB同様IDに、B:Basを処理する必要があります。うまくいきませんでした。id BB

次に、この問題に対する 2 つの解決策を見つけました。

grammar PrefixSolution1;
options       
{   
    language = Java;
}
goal: (size_prefix ':')? id;
size_prefix: B;
id: (LETTER | B)+;
LETTER: 'A' | 'C'..'Z' ;
B: 'B';
WSFULL:(' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;};

上記のコードでは、 がルールBから削除され、lexerルールに連結されていidます。

grammar PrefixSolution2;
options       
{   
    language = Java;
}
goal: PREFIX_VAR;
PREFIX_VAR: (B WSFULL* ':' WSFULL*)? ID;
fragment ID: (LETTER)+;
fragment LETTER: 'A'..'Z' ;
fragment B: 'B';
WSFULL:(' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;};

ここでは、ルールを に移動しましたlexer

PrefixSolution1レクサールールを小さなチャンクにストライプし、後で連結する必要があるという主な欠点があります。

PrefixSolution2: このアプローチは、無視すべき空白文字を常に考慮に入れる必要があることを示しています。

私にとっては、どちらのソリューションも、言語全体の文法を書くのに大きな混乱を招くことになります。他の解決策はありますか?そうでない場合、どの方法が最も最適ですか?

すべてのソースコードはこちらから入手できます

4

2 に答える 2

1

私はそれらのどちらとも行きません。トークンではなく、単純にIDトークンを作成します (またはトークンを作成します。これはパーサーに属します)。 BPREFIX_VAR

次のようなパーサー ルールで明確なセマンティック述語1を使用して、大文字の B ( capB) を一致させることができます。

grammar Test;

goal
 : (prefixVar | ID)+ EOF
 ;

prefixVar
 : capB ':' ID 
 ;

capB
 : {input.LT(1).getText().equals("B")}? ID
 ;

ID : LETTER+;
WS : (' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;};

fragment LETTER: 'A'..'Z' ;

これは、入力B:B B B:Cを次の解析ツリーに解析します。

ここに画像の説明を入力

1 ANTLR の「セマンティック述語」とは何ですか?

于 2012-04-26T11:57:20.117 に答える
0

これを試してください:

grammar PrefixProblem;


options       
{   
language = Java;
}

 goal: (size_prefix ':')? (id|B);

size_prefix: B;

id: LETTER+;

LETTER: 'A'|'C'..'Z' ;

B: 'B';

WSFULL:(' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;};
于 2012-04-26T11:42:06.607 に答える