我为布尔表达式创建了一个语法,现在我正在尝试实现访问者来评估它。
有人告诉我,不需要使用语义分析来复杂语法词法分析器和解析器规则,因为从访问者那里提供有意义的错误消息要好得多。
所以我正在尝试检查访问者中的类型一致性,日期正确性等。我得到的惊喜是没有办法(至少我没有看到它)报告来自访问者的错误而不是抛出异常。如果我抛出异常,我将无法继续进行表达式验证并立即检测所有错误。另外,我必须以某种方式捕获所有解析异常类型(我应该如何知道它们?)。总而言之,异常抛出似乎不是正确的解决方案。
您是否可以指导我如何计划在访问者遍历期间报告表达式语义中的错误?
答案 0 :(得分:6)
由于您定义了访问者,因此您可以创建并向其传递一个将报告错误的对象。
简单示例:
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和然后根据这些进行验证从长远来看可能会有所帮助。你需要决定它是否值得。