であいまいさを処理する方法を解決しようとしています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:B
asを処理する必要があります。うまくいきませんでした。id
B
B
次に、この問題に対する 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
: このアプローチは、無視すべき空白文字を常に考慮に入れる必要があることを示しています。
私にとっては、どちらのソリューションも、言語全体の文法を書くのに大きな混乱を招くことになります。他の解決策はありますか?そうでない場合、どの方法が最も最適ですか?
すべてのソースコードはこちらから入手できます