我为布尔表达式创建了一个语法,现在我正试图实现一个访问者来评估它。
有人告诉我们,没有必要用语义分析使语法词法分析器和解析器规则过于复杂,因为从访问者提供有意义的错误消息要好得多。
所以我试图检查类型一致性,日期正确性等在访问者。令我惊讶的是,除了抛出异常之外,没有办法(至少我没有看到)报告来自访问者的错误。如果我抛出一个异常,我将无法继续进行表达式验证并立即检测所有错误。此外,我必须以某种方式捕获所有解析异常类型(我应该如何知道它们?)总而言之,抛出异常似乎不是正确的解决方案。
你能给我一个方向是如何计划报告错误的表达式语义在访问者遍历期间?
既然定义了访问者,就可以创建并传递给它一个对象,它将向该对象报告错误。
简单的例子:
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
可以用于定位错误发生的位置(行/列等),但除此之外,您可以实现适合您的错误报告需求的任何内容。
旁注:如果您计划有许多访问者,那么构建AST和然后基于进行验证从长远来看可能是有益的。你需要决定这样做是否值得。