使用Antlr在运行时维护源位置

时间:2012-05-07 11:38:50

标签: antlr grammar

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

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

我试图将尽可能少的代码放入语法中以提高质量,例如我的(很多)表达式之一看起来像这样:

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

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

我希望,由于Antlr被许多脚本语言使用,因此有一种标准的方法来处理这个问题,因为源位置处理是一个方面,我不希望它在整个语法文件中混乱,而不是很干。

1 个答案:

答案 0 :(得分:1)

  

我希望,由于Antlr被许多脚本语言使用,因此有一种标准方法可以处理这个问题

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

您可以让运行时对象扩展CommonTree类,并让您的(组合)语法构造这些自定义运行时对象(您的类现在继承了getLine()getCharPositionInLine()方法)。请参阅:Using custom AST node types