2013-09-22 35 views
1

我想用antlr4爲我的簡單語法寫一些錯誤檢查。Antlr4,如何報告特定的語法錯誤

語法本身是由函數構造的。

FUNCTION hello (n){ 
    ...... 
} 
FUNCTION main (n) { 
    ...... 
} 

我不知道它是如何想捕獲特定的錯誤,例如缺少函數名,或缺少的主要功能

這裏是我的ErrorListener樣子

import org.antlr.v4.runtime.*; 
import org.antlr.v4.runtime.tree.*; 

public class SimpleErrorListener extends BaseErrorListener { 
    @Override 
    public void syntaxError(Recognizer<?, ?> recognizer, 
      Object offendingSymbol, 
      int line, 
      int charPositionInLine, 
      String msg, 
      RecognitionException e) { 
     List<String> stack = ((Parser) recognizer.getRuleInvocationStack(); 
     Collections.reverse(stack); 
     System.err.println("rule stack: " + stack); 
     System.err.println("line" + line + ":" + 
      charPositionInLine + "at" + offendingSymbol + ": " + msg); 
    } 
} 

我還刪除了控制檯錯誤偵聽器,並添加此o ne,但我不知道如何處理那些具體的錯誤。 任何建議表示讚賞。非常感謝。

回答

1

報告語義錯誤通常比報告語法錯誤容易得多。如果您想自定義報告語法錯誤,則需要更改語法,以便這些語法錯誤成爲語義錯誤。例如,如果你目前正在分析你的函數是這樣的:

function : FUNCTION ID '(' ... 

然後,您可以通過使用下列規則之一,而不是把「缺少函數名」到語法錯誤:

function : FUNCTION ID? '(' ... 

// alternate 
function : FUNCTION (ID | /*missing function name; reported in listener*/) '(' ... 

注意隨着您添加越來越多的特殊情況,您的語法將很快變得難以管理。

+0

嗨,@ 280Z28,非常感謝!我試圖編輯爲ID?在我的語法中,但它不報告。函數:「FUNCTION」ID?參數變量塊; – 4af2e9eb6

+0

然後我也試着看看它生成的消息到ErrorListener,並且我添加了if(msg.contains(「expecting ID」))System.out.println(「Error:function name undefined」); - >它確實報告,但我不確定它是否是正確的方法:) – 4af2e9eb6

+0

對於缺少主函數和重複函數名稱錯誤,我在語法中添加了一些謂詞,例如將所有函數名稱添加到本地HashSet以及如果有重複,則報告錯誤。但是,使用謂詞可能會導致多個錯誤消息:如果我有10個函數,並且它們都不是主函數,則通過使用此方法,它會打印10條錯誤消息,以便我認爲這種方法並不正確。 :( – 4af2e9eb6