简体   繁体   English

Antlr4如何检测无法识别的令牌和给定的句子无效

[英]Antlr4 how to detect unrecognized token and given sentence is invalid

I am trying to develop a new language with Antlr. 我正在尝试用Antlr开发一种新语言。 Here is my grammar file : 这是我的语法文件:

grammar test;

program : vr'.' to'.' e 
        ;
e: be
 | be'.' top'.' be
 ;
be: 'fg' 
  | 'fs' 
  | 'mc' 
  ;
to: 'n' 
  | 'a' 
  | 'ev' 
  ;
vr: 'er' 
  | 'fp' 
  ;
top: 'b' 
  | 'af' 
  ;
Whitespace : [ \t\r\n]+ ->skip 
           ;

Main.java Main.java

String expression = "fp.n.fss";
//String expression = "fp.n.fs.fs";
ANTLRInputStream input = new ANTLRInputStream(expression);
testLexer lexer = new testLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
testParser parser = new testParser(tokens);
//remove listener and add listener does not work
ParseTree parseTree = parser.program();

Everything is good for valid sentences. 对于有效的句子,一切都很好。 But I want to catch unrecognized tokens and invalid sentences in order to return meaningful messages. 但是我希望捕获无法识别的令牌和无效句子以便返回有意义的消息。 Here are two test cases for my problem. 以下是我的问题的两个测试用例。

fp.n.fss => anltr gives this error token recognition error at: 's' but i could not handle this error. fp.n.fss => anltr在:'s'给出了此错误令牌识别错误,但我无法处理此错误。 There are same example error handler class which use BaseErrorListener but in my case it does not work. 有相同的示例错误处理程序类使用BaseErrorListener但在我的情况下它不起作用。
fp.n.fs.fs => this sentence is invalid for my grammar but i could not catch. fp.n.fs.fs =>这句话对我的语法无效,但我无法抓住。 How can i catch invalidations like this sentence? 我怎么能抓住像这句话一样的失效?

Firstly welcome to SO and also to the ANTLR section! 首先欢迎来到SO和ANTLR部分! Error handling seems to be one of those topics frequently asked about, theres a really good thread here about handling errors in Java/ANTLR4 . 错误处理似乎是经常被问到的主题之一,这里有一个关于处理Java / ANTLR4中的错误的非常好的线程。

You most likely wanted to extend the functionality of the defaultErrorStrategy to handle the particular issues and handle them in a way differently that just printing the error line 1:12 token recognition error at: 's'. 您很可能希望扩展defaultErrorStrategy的功能来处理特定问题并以不同的方式处理它们,只需在:'s'打印错误行1:12令牌识别错误。

To do this you can implement your own version of the default error strategy class: 为此,您可以实现自己的默认错误策略类版本:

Parser parser = new testParser(tokens);
            parser.setErrorHandler(new DefaultErrorStrategy()
    {

        @Override
        public void recover(Parser recognizer, RecognitionException e) {
            for (ParserRuleContext context = recognizer.getContext(); context != null; context = context.getParent()) {
                context.exception = e;
            }

            throw new ParseCancellationException(e);
        }


        @Override
        public Token recoverInline(Parser recognizer)
            throws RecognitionException
        {
            InputMismatchException e = new InputMismatchException(recognizer);
            for (ParserRuleContext context = recognizer.getContext(); context != null; context = context.getParent()) {
                context.exception = e;
            }

            throw new ParseCancellationException(e);
        }
    });

 parser.program(); //back to first rule in your grammar

I would like to also recommend splitting your parser and lexer grammars up, if not for readability but also because many tools used to analyse the .g4 file (ANTLRWORKS 2 particularly) will complain about implicity declarations. 我还建议将解析器和词法分析器语法分开,如果不是为了可读性,还因为用于分析.g4文件的许多工具(特别是ANTLRWORKS 2)会抱怨隐含声明。

For your example it can be modified to the following structure: 对于您的示例,可以将其修改为以下结构:

grammar test;

program : vr DOT to DOT e 
        ;
e: be
 | be DOT top DOT be
 ;
be: FG 
  | FS
  | MC 
  ;
to: N
  | A 
  | EV
  ;
vr: ER 
  | FP 
  ;
top: B
  | AF
  ;
Whitespace : [ \t\r\n]+ ->skip 
           ;

DOT : '.'
    ;

A: 'A'|'a'
 ;

AF: 'AF'|'af'
 ;
N: 'N'|'n'
 ;
MC: 'MC'|'mc'
 ;
EV:'EV'|'ev'
 ;
FS: 'FS'|'fs'
 ;
FP: 'FP'|'fp'
 ;
FG: 'FG'|'fg'
 ;
ER: 'ER'|'er'
 ;
B: 'B'|'b'
 ;

You can also find all the methods available for the defaultErrorStrategy Class here and by adding those methods to your "new" error strategy implementation handle whatever exceptions you require. 您还可以在此处找到defaultErrorStrategy类的所有可用方法,并将这些方法添加到“新”错误策略实现中,处理您需要的任何异常。

Hope this helps and Good luck with your project! 希望这对您的项目有所帮助并祝您好运!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM