由於您定義了訪問者,您可以創建並向其傳遞一個對象,它將向其報告錯誤。
簡單的例子:
public interface IErrorReporter
{
void ReportError(ParserRuleContext context, string error);
}
public class ValidationVisitor : YourLanguageBaseVisitor<Whatever>
{
private readonly IErrorReporter _errorReporter;
public ValidationVisitor(IErrorReporter errorReporter)
{
_errorReporter = errorReporter;
}
public override Whatever VisitSomeNode(YourLanguageParser.SomeNodeContext context)
{
if (context.GetText() != "expected")
_errorReporter.ReportError(context, "Invalid text");
return Visit(context.someSubNode());
}
}
然後驗證這樣的:
var parseTree = DoTheParsingStuff();
// Implement that one, store the errors in a list
var errorReporter = new SimpleErrorReporter();
new ValidationVisitor(errorReporter).Visit(parseTree);
if (errorReporter.Errors.Count > 0)
{
// Display errors
}
的ParserRuleContext
可能是有用的定位發生錯誤(行/列等),但否則你可以實現任何適合你的錯誤報告需求的東西
旁註:如果您計劃有許多遊客,然後building an AST和然後基於在校驗可能是從長遠來看是有利的。你需要決定它是否值得。
謝謝你的回答。這是一個選項。你知道這是否是正確的做法或只是一種解決方法?正如我所看到的,Lexer和Parser具有用於報告錯誤的通用錯誤監聽器機制。我很驚訝訪客不。 –
這是我所做的簡化版本,它工作得很好。沒有*標準*方式,因爲您可以隨意在訪客/聽衆中做任何你想做的事情。詞庫/解析器需要錯誤報告機制,但訪問者和聽衆在一般情況下不需要這種機制。 –
另外值得注意的是,Lexer和Parser只報告語法錯誤。聽衆和訪問者可以通過檢查當前上下文,以前的值等來檢查語法正確的輸入是否在語義上有效 - 例如,國家代碼有兩個字母,但是「XX」是有效的國家代碼?這是一個我們開展業務的國家嗎?等等 –