1

我有一个基于 Antlr 的脚本语言:一个解析器和一个构建运行时对象(例如语句)的树语法。当我在运行时处理语句时,我想知道原始源位置(例如,当我抛出错误时,我想在脚本源中声明行和位置。)

将源位置附加到我的运行时对象的最佳策略是什么?如果我没有要求太多,我希望对我的语法文件的影响尽可能小。

我试图将尽可能少的代码放入语法中以提高质量,例如我的(许多)表达式之一如下所示:

multiplyExpression returns [Expression value]
: ^('*' l=expression r=expression)
{
    $value = sb.newBinaryExpression(CorIdentifier.MULTIPLY, $l.value, $r.value);
}
;

sb我在哪里ScriptBuilder充当生成的代码和我的运行时之间的适配器。我知道我可以将源位置作为附加参数添加到,newBinaryExpression但我也必须触摸所有其他表达式。我希望我可以只将令牌流放入 sb 一次并从流中获取源位置而完全不影响语法源。

我希望,由于许多脚本语言都使用 Antlr,因此有一种标准方法来处理这个问题,因为源位置处理是一个方面,我不想让它在整个语法文件中杂乱无章,而不是非常干燥。

4

1 回答 1

1

我希望,由于许多脚本语言都使用 Antlr,所以有一种标准的方法来处理这个问题

你让它听起来像 ANLTR 不支持这个。当然有:每个CommonTokenCommonTree对象都公开了公共getLine()getCharPositionInLine()方法,但是您丢弃这些实例并创建自己的节点(Expression)。将这些信息嵌入到您自己的节点中,不要感到惊讶 :)

您可以让您的运行时对象扩展CommonTree类并让您的(组合)语法构造这些自定义运行时对象(您的类现在继承getLine()andgetCharPositionInLine()方法)。请参阅:使用自定义 AST 节点类型

于 2012-05-08T17:42:37.477 回答