获取所有 Antlr 解析错误作为字符串列表


  • 如何在字符串列表中获取 Antlr 的所有解析错误?

我按如下方式使用 antlr:

ANTLRInputStream input = new ANTLRInputStream(System.in);
grLexer lexer = new grLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
grParser parser = new grParser(tokens);
ParseTree tree = parser.formula();
System.out.println(tree.toStringTree(parser));

例如

line 1:0 token recognition error at: '('
line 1:1 token recognition error at: ')'
line 1:2 token recognition error at: '('
  • 如何确定解析已执行而没有错误?如果只有一个解析错误,我会停止。

例如

if(tree.hasError()) // FOR EXAMPLE
   return;
  • 您需要提供ANTLRErrorListener的实现,以收集有关发生的错误的信息。例如,IntelliJ 插件使用其SyntaxErrorListener来跟踪此信息。

  • 您可以在解析完成后检查Parser.getNumberOfSyntaxErrors()以查看是否发生了错误。请注意,这不会报告来自词法分析器的错误。确保正确报告所有错误的最佳方法是编写词法分析器,使其本身永远不会遇到语法错误,而是将无效标记传递给解析器进行处理。

Sam Harwell描述的方式类似,以下代码演示了在调用分析器规则(如C分析器functionDefinition)后获取语法错误列表:

语法检查器:

import c.grammar.CLexer;
import c.grammar.CParser;
import org.antlr.v4.runtime.CodePointCharStream;
import org.antlr.v4.runtime.CommonTokenStream;
import java.util.List;
import static org.antlr.v4.runtime.CharStreams.fromString;
public class CSyntaxChecker
{
    public static List<SyntaxError> getSyntaxErrors(String sourceCode)
    {
        CodePointCharStream inputStream = fromString(sourceCode);
        CLexer lexer = new CLexer(inputStream);
        CommonTokenStream commonTokenStream = new CommonTokenStream(lexer);
        CParser parser = new CParser(commonTokenStream);
        SyntaxErrorListener listener = new SyntaxErrorListener();
        parser.addErrorListener(listener);
        parser.functionDefinition();
        return listener.getSyntaxErrors();
    }
}

语法错误侦听器:

import org.antlr.v4.runtime.BaseErrorListener;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Recognizer;
import org.antlr.v4.runtime.misc.Utils;
import java.util.ArrayList;
import java.util.List;
public class SyntaxErrorListener extends BaseErrorListener
{
    private final List<SyntaxError> syntaxErrors = new ArrayList<>();
    SyntaxErrorListener()
    {
    }
    List<SyntaxError> getSyntaxErrors()
    {
        return syntaxErrors;
    }
    @Override
    public void syntaxError(Recognizer<?, ?> recognizer,
                            Object offendingSymbol,
                            int line, int charPositionInLine,
                            String msg, RecognitionException e)
    {
        syntaxErrors.add(new SyntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e));
    }
    @Override
    public String toString()
    {
        return Utils.join(syntaxErrors.iterator(), "n");
    }
}

语法错误:

import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Recognizer;
public class SyntaxError
{
    private final Recognizer<?, ?> recognizer;
    private final Object offendingSymbol;
    private final int line;
    private final int charPositionInLine;
    private final String message;
    private final RecognitionException e;
    SyntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e)
    {
        this.recognizer = recognizer;
        this.offendingSymbol = offendingSymbol;
        this.line = line;
        this.charPositionInLine = charPositionInLine;
        this.message = msg;
        this.e = e;
    }
    public Recognizer<?, ?> getRecognizer()
    {
        return recognizer;
    }
    public Object getOffendingSymbol()
    {
        return offendingSymbol;
    }
    public int getLine()
    {
        return line;
    }
    public int getCharPositionInLine()
    {
        return charPositionInLine;
    }
    public String getMessage()
    {
        return message;
    }
    public RecognitionException getException()
    {
        return e;
    }
}

相关内容

  • 没有找到相关文章

最新更新