ANTLR4:我可以';我不明白

ANTLR4:我可以';我不明白,antlr,antlr4,Antlr,Antlr4,我对ANTLR4非常陌生,正在尝试构建自己的语言。所以我的语法从 program: <EOF> | statement | functionDef | statement program | functionDef program; 及 现在的问题是,当我根据selectionStatement或statement测试一段代码时,它通过了测试,但当我根据程序测试它时,它无法识别。有人能帮我吗?多谢各位 编辑:我用于测试的代码如下: if (x == 2) {} 它通过了对选择语

我对ANTLR4非常陌生,正在尝试构建自己的语言。所以我的语法从

program: <EOF> | statement | functionDef | statement program | functionDef program;

现在的问题是,当我根据
selectionStatement
statement
测试一段代码时,它通过了测试,但当我根据
程序测试它时,它无法识别。有人能帮我吗?多谢各位


编辑:我用于测试的代码如下:

if (x == 2) {}
它通过了对
选择语句
语句
的测试,但在
程序
中失败。似乎
程序
仅接受
if…else

if (x == 2) {} else {}

编辑2: 我收到的错误消息是

<unknown>: Incorrect error: no viable alternative at input 'if(x==2){}'
:错误:输入'if(x==2){}'时没有可行的替代方案

无法回答您的问题,因为提供的信息不完整:语句规则是部分的,而compoundStatement规则缺失

尽管如此,您应该使用两种技巧自己回答此类问题(除了单元测试)

首先,确保lexer按预期工作。显示如何直接转储令牌流

第二,使用定制的ErrorListener为每个遇到的错误提供有意义/详细的解析路径描述。例如:

public class JavaErrorListener extends BaseErrorListener {

    public int lastError = -1;

    @Override
    public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine,
            String msg, RecognitionException e) {

        Parser parser = (Parser) recognizer;
        String name = parser.getSourceName();
        TokenStream tokens = parser.getInputStream();

        Token offSymbol = (Token) offendingSymbol;
        int thisError = offSymbol.getTokenIndex();
        if (offSymbol.getType() == -1 && thisError == tokens.size() - 1) {
            Log.debug(this, name + ": Incorrect error: " + msg);
            return;
        }
        String offSymName = JavaLexer.VOCABULARY.getSymbolicName(offSymbol.getType());

        List<String> stack = parser.getRuleInvocationStack();
        // Collections.reverse(stack);

        Log.error(this, name);
        Log.error(this, "Rule stack: " + stack);
        Log.error(this, "At line " + line + ":" + charPositionInLine + " at " + offSymName + ": " + msg);

        if (thisError > lastError + 10) {
            lastError = thisError - 10;
        }
        for (int idx = lastError + 1; idx <= thisError; idx++) {
            Token token = tokens.get(idx);
            if (token.getChannel() != Token.HIDDEN_CHANNEL) Log.error(this, token.toString());
        }
        lastError = thisError;
    }
}
公共类JavaErrorListener扩展了BaseErrorListener{
public int lastError=-1;
@凌驾
public void syntaxError(识别器识别器、对象违规符号、int-line、int-charPositionInLine、,
字符串消息,识别异常(e){
解析器=(解析器)识别器;
String name=parser.getSourceName();
TokenStream tokens=parser.getInputStream();
Token offSymbol=(Token)offingsymbol;
int thisrerror=offSymbol.getTokenIndex();
if(offSymbol.getType()=-1&&thisError==tokens.size()-1){
Log.debug(此,名称+”:错误:“+msg”);
返回;
}
字符串offSymName=JavaLexer.词汇表.getSymbolicName(offSymbol.getType());
List stack=parser.getRuleInvocationStack();
//集合。反向(堆栈);
Log.error(此,名称);
Log.error(此“规则堆栈:“+stack”);
Log.error(这是“在行”+line+:“+charPositionInLine+”在“+offSymName+”:“+msg”);
如果(此错误>上次错误+10){
lastError=此错误-10;
}

对于(int idx=lastError+1;idx感谢您的帮助。我编辑了此问题,使其包含compoundStatement的实现。我已确认lexer按预期工作,并将从
errorListener
收到的错误放在上次编辑中。我仍然找不到问题的解释或解决方案。您可以吗看看我?基于不完整的信息仍然无法回答。什么是完整的语句规则?什么是完整的错误消息(错误侦听器发出更多有价值的信息)?什么是完整的令牌流转储?基于您自己对这些信息的分析,您自己的问题和结论是什么?
<unknown>: Incorrect error: no viable alternative at input 'if(x==2){}'
public class JavaErrorListener extends BaseErrorListener {

    public int lastError = -1;

    @Override
    public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine,
            String msg, RecognitionException e) {

        Parser parser = (Parser) recognizer;
        String name = parser.getSourceName();
        TokenStream tokens = parser.getInputStream();

        Token offSymbol = (Token) offendingSymbol;
        int thisError = offSymbol.getTokenIndex();
        if (offSymbol.getType() == -1 && thisError == tokens.size() - 1) {
            Log.debug(this, name + ": Incorrect error: " + msg);
            return;
        }
        String offSymName = JavaLexer.VOCABULARY.getSymbolicName(offSymbol.getType());

        List<String> stack = parser.getRuleInvocationStack();
        // Collections.reverse(stack);

        Log.error(this, name);
        Log.error(this, "Rule stack: " + stack);
        Log.error(this, "At line " + line + ":" + charPositionInLine + " at " + offSymName + ": " + msg);

        if (thisError > lastError + 10) {
            lastError = thisError - 10;
        }
        for (int idx = lastError + 1; idx <= thisError; idx++) {
            Token token = tokens.get(idx);
            if (token.getChannel() != Token.HIDDEN_CHANNEL) Log.error(this, token.toString());
        }
        lastError = thisError;
    }
}