在Antlr4中强制语法错误

时间:2018-01-08 21:27:05

标签: java antlr4

我已经搜索了几个小时试图弄清楚如何在Antlr4侦听器中手动创建语法错误。有可能吗?

我创建了一个工作正常的语法,其中一部分看起来像:

variableExp returns [ BigDecimal value ]
  : VARIABLE_PREFIX n = VARIABLE_NAME 
  ;

其中VARIABLE_PREFIX是一个像“$”的字符。

我正在使用一个监听器,在exitVariableExp()上,我根据解析器外部的信息设置了值(并且输入了用户,因此我无法将其放入解析器中):

  @Override 
  public void exitVariableExp(ExpressionsParser.VariableExpContext ctx) 
  { 
    System.out.println("In exitVariableExp()");
    ctx.value = lookupVariable(ctx.getText());
  }

我遇到的问题是用户可以输入任何不是变量的东西(例如$ jfjhfjfj),这将被解析器接受。我想在此侦听器成员中创建语法错误,因为我有一个错误侦听器,它存储语法错误位置以向用户显示:

@Override
public void syntaxError(Recognizer<?, ?> recognizer, Object   offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) throws ParseCancellationException 
  {
    System.out.println("Got syntax error.");
    errorLine = line;
    errorColumn = charPositionInLine;
    errorMessage = msg;
  }

但我无法弄明白该怎么做。也许这是错误的方法呢?

2 个答案:

答案 0 :(得分:2)

执行tree-walker时,解析器已经运行完成,因此解析器的语法错误报告机制不可用。

更好,只需依赖解析树节点,因为它将包含报告错误所需的所有信息。

private static final String msg = "Syntax error: '%s' is not a valid var (at %s:%s).";

@Override 
public void exitVariableExp(VariableExpContext ctx) { 
    String value = lookupVariable(ctx.getText());
    if (value == null || value.isEmpty()) {
        Token tok = ctx.VARIABLE_NAME.getSymbol();
        int line = tok.getLine();              // 1..n
        int col = tok.getCharPositionInLine(); // 0..n
        System.out.println(String.format(msg, tok.getText(), line, col));            
    }
}

答案 1 :(得分:0)

尝试解析器在遇到语法错误时正在执行的操作:它会抛出RecognitionException。您可以在监听器中执行此操作,异常处理将注意并报告错误(并尝试恢复)。如果您不喜欢恢复机制并想要完全停止解析,则需要进行更多工作。在这种情况下,您应该抛出一个不同于RecognitionException的异常(因为它会在所有解析器函数中捕获)。 BailErrorStrategy使用此方法尽快停止解析(这对于快速语法检查很有用)。看那里如何覆盖一些标准行为。