簡體   English   中英

如何使用C ++捕獲antlr4中的解析異常?

[英]How to catch parse exceptions in antlr4 using C++?

我正在使用antlr4 c ++目標。 我不知道如何捕獲解析異常,也找不到有關它的文檔。

我已經嘗試使用parser.setErrorHandler(std::make_shared<antlr4::BailErrorStrategy>()); ,但會引發其“ e.what()”為空的異常。

try {
    ANTLRInputStream instream(sql);
    MyLexer lexer(&instream);
    CommonTokenStream tokens(&lexer);
    MyParser parser(&tokens);
               // parser.setErrorHandler(std::make_shared<antlr4::BailErrorStrategy>());

    auto ctx = parser.singleStatement();
    ...
    } catch(ParseCancellationException& e) {
        std::cout << string(e.what()) << std::endl;
        throw MyParseException(e.what());
    } catch (std::exception& e) {
        std::cout << e.what() << std::endl;
    }

我希望捕獲到異常消息,例如“行1:19缺少';'” 在“”處,然后使用我自己的異常類型將其重新拋出。

ParseCancellationException s不包含有關遇到的語法錯誤的任何信息,因此它們不適合錯誤報告。 BailErrorStrategy實際上僅適用於您不想報告錯誤的情況。

相反,您應該堅持默認的錯誤處理策略,並注冊自己的錯誤偵聽器(在使用removeErrorListeners刪除默認錯誤偵聽器之后,除非您希望報告和/或處理錯誤消息的方法之外,仍將錯誤消息打印到stderr,錯誤)。 將使用正確報告錯誤所需的所有信息來調用錯誤偵聽器。 然后,您可以直接使用該信息引發異常,也可以將錯誤信息存儲在向量中,然后在解析器完成后引發包含有關所有語法錯誤信息的異常。

沒有可以捕獲的解析異常。 ParseCancellationException非常特殊,因為它用於實施早期退出策略(通常與兩階段方法結合使用以在SLL模式下開始解析(對於語法正確的輸入而言更快),並在以下情況下繼續使用LL模式第一階段是失敗的,因此會繞過所有通常在解析錯誤時出現的catch子句。

捕獲解析錯誤的正確方法是(已提到sepp2k),方法是添加您自己的錯誤偵聽器,該偵聽器將使用所有必要的信息(位置,違規令牌等)進行調用,以便您可以為用戶創建自己的錯誤。

我已經在MySQL Workbench中實現了該方法。 檢查解析步驟詞法分析器以及解析器錯誤處理的代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM