所以我正在试验 Antlr v4,我正在用一些不寻常的语法戳它,以了解它是如何工作的。这是我当前的测试用例:
我想要一个按顺序由字母 A、B、C、D 组成的语法。字母可能会重复。我还将 A 和 B 组合在一起,C 和 D 也组合在一起,以使语法更有趣。所以像这样的字符串是可以接受的语法:
AAA
A B C D
ACCCDD
但这并不顺利。我认为正在发生的事情是 Antlr 需要一个更好的语法退出规则。它似乎没有认识到在收集了 A 和 B 之后,C 的存在意味着进入下一个规则。实际上它有点工作,但我收到错误消息,生成的解析树似乎有空元素,就像它在发出错误消息的地方插入了一个额外的元素。
这是一个示例错误消息:
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)
任何帮助深表感谢。