Использование токенов ошибок в antlr4
Вот моя грамматика, которую я пытаюсь представить как
alter table ;
все работает нормально но когда даю
altasder table; alter table ;
это дает мне ошибку в первой строке, как и ожидалось, но я хочу, чтобы проанализировать вторую команду, игнорируя первую 'altasder table;
'
grammar Hello;
start : compilation;
compilation : sql*;
sql : altercommand;
altercommand : ALTER TABLE SEMICOLON;
ALTER: 'alter';
TABLE: 'table';
SEMICOLON : ';';
как я могу достичь этого???
Я использовал Stategy DefualtError, но до сих пор не wotking
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);
}
}
}
основной класс: публичный класс Main {
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));
}
}
myoutput:
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)
почему его не перейти ко второй команде?
1 ответ
Нужно использовать 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
при необходимости укажите следующую действительную точку для возобновления распознавания.
Обратите внимание, что сообщения об ошибках вызваны тем, что лексер не может сопоставить посторонние вводимые символы. Чтобы удалить сообщения об ошибках, добавьте в качестве последнего правила лексера:
ERR_TOKEN : . ;