gpt4 book ai didi

error-handling - 如何让 ANTLR 3.2 在第一次出错时退出?

转载 作者:行者123 更新时间:2023-12-04 06:12:20 26 4
gpt4 key购买 nike

在第 10.4 节中,Definitive ANTLR 引用告诉您,如果您想在第一个解析错误时退出,请覆盖 mismatch() 和 recoverFromMismatchedSet()。但是,至少在 ANTLR 3.2 中,似乎没有 mismatch() 方法,并且 recoveryFromMismatchedSet() 文档说它“当前未使用”。因此,自该书出版以来,情况似乎发生了变化。

我应该怎么做才能在 ANTLR 3.2 中出现第一个解析错误时退出?

最佳答案

我将此问题发布到 anltr-interest,Andrew Haritonkin 回答了。 Bart K 说对了一半;您需要覆盖recoverFromMismatchedSet(),还需要recoverFromMismatchedToken()。

如果您还希望词法分析器在出现第一个错误时退出,有一个 wiki 页面解释了该怎么做:

http://www.antlr.org/wiki/pages/viewpage.action?pageId=5341217

简而言之,它指出:

  • 如果你想抛出 RecognitionException(或任何继承自 Exception 的东西),那么你必须做一些偷偷摸摸的 java 技巧,因为相关的方法没有声明任何异常
  • 如果可以抛出 RuntimeException 或 Error,那么您可以覆盖 nextToken() 以抛出异常而不是调用 recoveryError(),或者您可以覆盖 recoveryError()。抛出异常。

  • 这是在第一个词法分析器或解析器错误时退出的示例语法:
    grammar Test;

    @parser::members {

    public static void main(String[] args) throws Exception {
    String text = args[0];
    ANTLRStringStream in = new ANTLRStringStream(text);
    TestLexer lexer = new TestLexer(in);
    CommonTokenStream tokens = new CommonTokenStream(lexer);
    System.out.println(new TestParser(tokens).mainRule());
    }

    @Override
    protected Object recoverFromMismatchedToken(IntStream input, int ttype, BitSet follow) throws RecognitionException {
    throw new MismatchedTokenException(ttype, input);
    }

    @Override
    public Object recoverFromMismatchedSet(IntStream input, RecognitionException e, BitSet follow) throws RecognitionException {
    throw e;
    }

    }

    @rulecatch {
    catch (RecognitionException e) {
    throw e;
    }
    }

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

    }

    mainRule returns [List<String> words]
    @init{$words = new ArrayList<String>();}
    : w=Atom {$words.add($w.text);} (',' w=Atom {$words.add($w.text);} )* EOF
    ;


    Atom: '0' | '1';

    WS : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+ { $channel = HIDDEN; } ;

    示例输出:
    C:\Users\dan\workspace\antlrtest>java -cp .;antlr-3.2.jar TestParser "1,0" 
    [1, 0]

    C:\Users\dan\workspace\antlrtest>java -cp .;antlr-3.2.jar TestParser "1,,0"
    Exception in thread "main" MismatchedTokenException(6!=4)
    at TestParser.recoverFromMismatchedToken(TestParser.java:45)
    at org.antlr.runtime.BaseRecognizer.match(BaseRecognizer.java:115)
    at TestParser.mainRule(TestParser.java:86)
    at TestParser.main(TestParser.java:40)

    C:\Users\dan\workspace\antlrtest>java -cp .;antlr-3.2.jar TestParser "1,+0"
    Exception in thread "main" java.lang.RuntimeException: NoViableAltException('+@[])
    at TestLexer.reportError(TestLexer.java:16)
    at org.antlr.runtime.Lexer.nextToken(Lexer.java:94)
    at org.antlr.runtime.CommonTokenStream.fillBuffer(CommonTokenStream.java:119) at org.antlr.runtime.CommonTokenStream.LT(CommonTokenStream.java:238)
    at org.antlr.runtime.Parser.getCurrentInputSymbol(Parser.java:54)
    at org.antlr.runtime.BaseRecognizer.match(BaseRecognizer.java:104)
    at TestParser.mainRule(TestParser.java:68)
    at TestParser.main(TestParser.java:40)
    Caused by: NoViableAltException('+'@[])
    at TestLexer.mTokens(TestLexer.java:165)
    at org.antlr.runtime.Lexer.nextToken(Lexer.java:84)
    ... 6 more

    关于error-handling - 如何让 ANTLR 3.2 在第一次出错时退出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2445008/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com