在antlr4中使用错误标记

在antlr4中使用错误标记,antlr,antlr4,antlr3,antlr2,Antlr,Antlr4,Antlr3,Antlr2,这是我的语法,我试着作为输入 alter table ; 一切都很好,但当我 altasder table; alter table ; 它在第一个字符串上给出了一个错误,但我想解析第二个命令,忽略第一个'altasder表' grammar Hello; start : compilation; compilation : sql*; sql : altercommand; altercommand : ALTER TABLE SEMICOLON; ALTER: 'alter'; TAB

这是我的语法,我试着作为输入

alter table ;
一切都很好,但当我

altasder table; alter table ;
它在第一个字符串上给出了一个错误,但我想解析第二个命令,忽略第一个'
altasder表'

grammar Hello;

start : compilation;
compilation : sql*;
sql : altercommand;
altercommand : ALTER TABLE SEMICOLON;
ALTER: 'alter';
TABLE: 'table';
SEMICOLON : ';';
我怎样才能实现它

我已经使用了解除武装的策略,但它仍然不起作用

import org.antlr.v4.runtime.DefaultErrorStrategy;
import org.antlr.v4.runtime.Parser;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.TokenStream;
import org.antlr.v4.runtime.misc.IntervalSet;

public class CustomeErrorHandler extends DefaultErrorStrategy {


        @Override
        public void recover(Parser recognizer, RecognitionException e) {
        // TODO Auto-generated method stub
        super.recover(recognizer, e);


            TokenStream tokenStream = (TokenStream)recognizer.getInputStream();


            if (tokenStream.LA(1) == HelloParser.SEMICOLON  )
            {

                IntervalSet intervalSet = getErrorRecoverySet(recognizer);

                tokenStream.consume();

                consumeUntil(recognizer, intervalSet);
            }
        }
    }
主要类别: 公共班机{

public static void main(String[] args) throws IOException {
    ANTLRInputStream ip = new ANTLRInputStream("altasdere table ; alter table ;");
    HelloLexer lex = new HelloLexer(ip); 
    CommonTokenStream token = new CommonTokenStream(lex);
    HelloParser parser = new HelloParser(token);
    parser.setErrorHandler(new CustomeErrorHandler());
    System.out.println(parser.start().toStringTree(parser));

}

}
输出:

line 1:0 token recognition error at: 'alta'
line 1:4 token recognition error at: 's'
line 1:5 token recognition error at: 'd'
line 1:6 token recognition error at: 'e'
line 1:7 token recognition error at: 'r'
line 1:8 token recognition error at: 'e'
line 1:9 token recognition error at: ' '
(start compilation)

为什么不移动到第二个命令?

需要使用
DefaultErrorStrategy
来控制解析器如何响应识别错误。根据需要进行扩展,修改
#recover
方法,以使用令牌,直到令牌流中所需的解析重新启动点

#recover
的简单实现是:

@Override
public void recover(Parser recognizer, RecognitionException e) {
    if (e instanceof InputMismatchException) {
        int ttype = recognizer.getInputStream().LA(1);
        while (ttype != Token.EOF && ttype != HelloParser.SEMICOLON) {
            recognizer.consume();
            ttype = recognizer.getInputStream().LA(1);
        }
    } else {
        super.recover(recognizer, e);
    }
}
根据需要调整
while
条件,以确定下一个恢复识别的有效点

注意,错误消息是由于lexer无法匹配无关的输入字符。若要删除错误消息,请将添加为最后一个lexer规则:

ERR_TOKEN : . ;

您好@GRosenberg感谢您的回复,我使用了DefaultErrorStrategy,但仍然无法获得使用错误策略类plz help编辑的正确结果。感谢@GRosenberg,我已按照您所说的添加了代码,但控件没有使用recover方法,我已输入“AltasDefer table;alter table;”但将输出作为第1:0行的令牌识别错误:alta第1:4行的令牌识别错误:'s'第1:5行的令牌识别错误:'d'第1:6行的令牌识别错误:'f'第1:7行的令牌识别错误:'e'第1:8行的令牌识别错误:'r'第1:9行的令牌识别错误:''(开始编译)“请帮助我解决这个问题。”GRosenberg在使用recover方法进行查询时说:“altasder table;alter table;它在第一个分号(;)之前一直使用令牌.它不处理正确的第二条语句。你能告诉我吗guide@GRosenberg将错误状态处理到分号后,它应该再次从第一条规则开始。如何实现