1、antlr4 错误处理
默认情况下,ANTLR将所有的错误消息送至标准错误(standard error),不过我们可以通过实现接口ANTLRErrorListener来改变这些消息的目标输出和内容。
该接口有一个同时应用于词法分析器和语法分析器的syntaxError()方法。syntaxError()方法接收各式各样的信息,无论是错误的位置还是错误的内容。它还接收指向语法分析器的引用,因此我们能够通过该引用来查询识别过程的状态。
2、添加错误处理
1、创建错误处理类ErrorListener
java
public class ErrorListener extends BaseErrorListener {
private String regex;
public ErrorListener(String regex) {
this.regex = regex;
}
@Override
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line,
int charPositionInLine, String msg, RecognitionException e) {
super.syntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e);
String content = regex.substring(0, charPositionInLine + 1);
StaticLog.error("regex parse syntax error: expression = {}, msg = {}", regex, msg);
throw new RuntimeException("第" + line + "行,语法错误,错误内容:" + content + ",错误消息:" + msg);
}
}
2、添加错误监听器
使用这种方法,我们的程序就能在语法分析器调用起始规则之前,轻易地为其增加一个错误监听器。
在我们增加自定义的错误监听器之前,我们需要移除输出目标是控制台的内置错误监听器,以防出现重复的错误消息。
ini
public static String gen(String regex) {
if (regex.startsWith("^")) {
regex = regex.substring(1);
}
if (regex.endsWith("$")) {
regex = regex.substring(0,regex.length()-1);
}
ErrorListener errorListener = new ErrorListener(regex);
regexLexer regexLexer = new regexLexer(CharStreams.fromString(regex));
// 移除默认的错误监听器
regexLexer.removeErrorListeners();
// 添加新的错误监听器
regexLexer.addErrorListener(errorListener);
CommonTokenStream tokens = new CommonTokenStream(regexLexer);
regexParser parser = new regexParser(tokens);
// 移除默认的错误监听器
parser.removeErrorListeners();
// 添加新的错误监听器
parser.addErrorListener(errorListener);
regexParser.RootContext root = parser.root();
RegVistor2 regexVisitor = new RegVistor2();
return regexVisitor.visitRoot(root);
}
3、测试代码
csharp
System.out.println(RegexUtil.gen("([)11]{aaaqqqxx2"));
输出如下:
css
[2024-01-31 09:18:45] [ERROR] com.regex.ErrorListener: regex parse syntax error: expression = ([)11]{aaaqqqxx2, msg = token recognition error at: 'a'
Exception in thread "main" java.lang.RuntimeException: 第1行,语法错误,错误内容:([)11]{a,错误消息:token recognition error at: 'a'