我有一个基于Antlr的脚本语言:一个解析器和一个构建运行时对象(例如语句)的树语法。当我在运行时处理语句时,我想知道原始源位置(例如,当我抛出错误时,我想在脚本源中说明行和位置。)
将源位置附加到运行时对象的最佳策略是什么?如果我没有要求太多,我想尽可能少地对我的语法文件产生影响。
我试图将尽可能少的代码放入语法中以提高质量,例如我的(很多)表达式之一看起来像这样:
multiplyExpression returns [Expression value]
: ^('*' l=expression r=expression)
{
$value = sb.newBinaryExpression(CorIdentifier.MULTIPLY, $l.value, $r.value);
}
;
其中sb
是我的ScriptBuilder
,它充当生成的代码和我的运行时之间的适配器。我知道我可以将源位置添加为newBinaryExpression
的附加参数,但是我还必须触摸所有其他表达式。我希望我只能将令牌流放入sb一次,然后从流中获取源位置,而不会影响语法源。
我希望,由于Antlr被许多脚本语言使用,因此有一种标准的方法来处理这个问题,因为源位置处理是一个方面,我不希望它在整个语法文件中混乱,而不是很干。
答案 0 :(得分:1)
我希望,由于Antlr被许多脚本语言使用,因此有一种标准方法可以处理这个问题
你听起来好像ANLTR不支持这个。当然有:每个CommonToken
和CommonTree
个对象都公开了公共getLine()
和getCharPositionInLine()
方法,但您放弃这些实例并创建自己的节点(Expression
)。将这些信息嵌入您自己的节点时,不要感到惊讶:)
您可以让运行时对象扩展CommonTree
类,并让您的(组合)语法构造这些自定义运行时对象(您的类现在继承了getLine()
和getCharPositionInLine()
方法)。请参阅:Using custom AST node types。