ANTLR检查commontree是否正确或如何检查给定输入是否与ANTLR语法匹配?

时间:2012-02-22 22:10:35

标签: java compiler-construction antlr finite-automata antlrworks

您好我想做一个java或c#方法,它会根据给定的输入返回一个布尔表达式true或false。例如:

if(输入与antlr语法匹配)      返回true;  其他      返回false; 所以问题是我不知道如何检查commontree是否有任何mismatchetoken。我试图遍历树,但它不会给作为树节点的任何不匹配。可能问题是AST没有显示不匹配的令牌只有解析树。如果有人告诉我如何从解析器获取parsetree,那也可能有帮助吗?

我已经完成了ANTLR .g文件并且它运行良好,现在我需要执行以下操作:我必须检查输入是否正确,我已经完成了但是它不起作用:

 public static boolean check() {
    String file = "test.txt";
    ANTLRReaderStream input;
    try{

            input = new ANTLRReaderStream(new FileReader(file));
            regExLexer lexer = new regExLexer(input);
            CommonTokenStream tokens = new CommonTokenStream(lexer);
            regExParser parser = new regExParser(tokens);

            CommonTree root = (CommonTree)parser.goal().getTree();

        return true;}
catch{
return false;}
}

所以我希望我的方法只在输入字符串正确时返回true,否则返回false。我这样做的方式总是返回true,但是当字符串不正确时,它会打印

  

“第1行:4个无关输入'+'期待EOF”

在控制台中。

2 个答案:

答案 0 :(得分:1)

正如我在您的问题中的评论中暗示的那样:this previous Q&A回答了您的问题。我将举例说明。

假设您有一个接受数字的语法(并忽略空格)。您只需覆盖解析器和词法分析器的reportError并在该方法中抛出异常:解析器(或词法分析器)将不会继续。抓住错误,只需在false辅助方法中返回static

grammar T;

@parser::members {

  public static boolean matches(String input) {
    try {
      TLexer lexer = new TLexer(new ANTLRStringStream(input));
      TParser parser = new TParser(new CommonTokenStream(lexer));
      parser.parse();
      return true;
    } catch(Exception e) {
      return false;
    }
  }

  @Override
  public void reportError(RecognitionException e) {
    throw new RuntimeException(e); 
  }
}

@lexer::members {
  @Override
  public void reportError(RecognitionException e) {
    throw new RuntimeException(e); 
  }
}

parse
 : NUMBER* EOF
 ;

NUMBER : '0'..'9'+;
SPACE  : ' ' {skip();};

现在正在运行课程:

import org.antlr.runtime.*;

public class Main {
  public static void main(String[] args) throws Exception {
    System.out.println(TParser.matches(""));
    System.out.println(TParser.matches("1 234 42"));
    System.out.println(TParser.matches("12 556 f"));
  }
}

将打印:

true
true
false

答案 1 :(得分:0)

ANTLR会为你恢复一些错误(比如错过一个明显的说法),如果你不熟悉它可能会很痛苦。

如果您愿意,可以覆盖regExParser类中的BaseRecognizer.recoverFromMismatchedToken并始终抛出异常,因为找到了不匹配的标记。

参考:

ANTLR: error recovery and reporting