そこで、私は Antlr v4 で実験を行っており、それがどのように機能するかを理解するために、いくつかの変わった文法を試しています。現在のテスト ケースは次のとおりです。
A、B、C、D の順に文字を並べた文法をお願いします。文字が繰り返されることがあります。また、文法をより面白くするために、A と B をグループ化し、C と D もグループ化します。したがって、次のような文字列は許容される文法です。
AAA
あいうえお
ACCCDD
しかし、うまくいっていません。起こっていることは、Antlr が私の文法に対してより良い終了規則を必要としているということだと思います。A と B を収集した後、C の存在が次のルールに進むことを意味することを認識していないようです。実際には機能していますが、エラーメッセージが表示され、結果の解析ツリーには、エラーメッセージを発行した場所に余分な要素が挿入されたように、null 要素が含まれているようです。
エラー メッセージの例を次に示します。
line 1:2 extraneous input 'C' expecting {'B', 'A'}
これは、入力「ABCD」に対して発生します。そのため、Antlr がそこにある C を見ると、何か奇妙なことが起こっています。解析ツリーの出力は次のとおりです。
'ABCD': (prog (aOrB (a A) (aOrB (b B) aOrB)) (cOrD (c C) (cOrD (d D) cOrD)) <EOF>)
最初の要素セットの最後に空の aOrB 要素があることがわかります。
何が起こっているのですか?エラーを発行して空の要素を追加するとき、Antlrはここで何を「考えている」のでしょうか? そして、どうすればこれを修正できますか?
わかりました、ここに悲惨な詳細があります。
私の文法:
grammar Abcd;
prog : aOrB cOrD EOF;
aOrB : ( a | b ) aOrB ;
a : 'A'+ ;
b : 'B'+ ;
cOrD : ( c | d ) cOrD ;
c : 'C'+ ;
d : 'D'+ ;
Javaでの私のテストプログラム:
package antlrtests;
import antlrtests.grammars.*;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;
class AbcdTest {
private final String[] testVectors = {
"A", "AABB", "B", "ABCD", "C", "D", };
public void runTests() {
for( String test : testVectors )
simpleTest( test );
}
private void simpleTest( String test ) {
ANTLRInputStream ains = new ANTLRInputStream( test );
AbcdLexer wpl = new AbcdLexer( ains );
CommonTokenStream tokens = new CommonTokenStream( wpl );
AbcdParser wikiParser = new AbcdParser( tokens );
ParseTree parseTree = wikiParser.prog();
System.out.println( "'" + test + "': " + parseTree.toStringTree(
wikiParser ) );
}
}
そして私のテストプログラムの出力。Antlr によって標準エラーに出力されるため、エラー メッセージが通常の出力と混同されていることに注意してください。
run:
line 1:1 no viable alternative at input '<EOF>'
'A': (prog (aOrB (a A) aOrB) cOrD <EOF>)
line 1:4 no viable alternative at input '<EOF>'
'AABB': (prog (aOrB (a A A) (aOrB (b B B) aOrB)) cOrD <EOF>)
'B': (prog (aOrB (b B) aOrB) cOrD <EOF>)
line 1:1 no viable alternative at input '<EOF>'
line 1:2 extraneous input 'C' expecting {'B', 'A'}
line 1:4 no viable alternative at input '<EOF>'
'ABCD': (prog (aOrB (a A) (aOrB (b B) aOrB)) (cOrD (c C) (cOrD (d D) cOrD)) <EOF>)
line 1:0 no viable alternative at input 'C'
line 1:1 no viable alternative at input '<EOF>'
line 1:0 no viable alternative at input 'D'
'C': (prog aOrB (cOrD (c C) cOrD) <EOF>)
line 1:1 no viable alternative at input '<EOF>'
'D': (prog aOrB (cOrD (d D) cOrD) <EOF>)
BUILD SUCCESSFUL (total time: 0 seconds)
どんな助けでも大歓迎です。