您如何在Antlr4的语法操作中引用可选规则“规则名称”?

时间:2019-02-19 15:45:13

标签: parsing compiler-construction antlr antlr4

TL; DR::如何从语法动作中引用可选规则rulename?


我尝试了此操作,但显然失败了,因为当None规则不匹配时, $ value value(空),并且访问空引用的属性会产生错误:

| NOP3 value? {print( $value.ret )}

然后我尝试了此操作,但是现在我得到一个错误,即我无法引用RuleContext $ value 本身,但必须引用其属性之一:( error(67) :缺少对$ value中的规则参考值的属性访问

| NOP3 value? {print( $value.ret if $value is not None else "empty" )}

我能够通过这种肮脏的解决方案来工作,该解决方案将注入自定义的hacky代码,该代码将插入子规则 value 不匹配时触发的if if else子句,但这很丑陋,我猜对此应该有一个更好的解决方案:

    | NOP3 value? {else:
    class obj(object):
        pass    
    localctx._value = obj()
    localctx._value.ret = None
print( $value.ret )}  

注意: $ value.ret 是子规则的返回值。

编辑:关于 Bart Kiers 的迭代:
 因为如果 value 子规则不匹配,我真的不需要做任何事情,所以我能够像这样简化它:

| NOP3 ( value {do_something()} )?  

因此,基本上将value?设为子规则,并将操作嵌入其中,而不是父规则。

1 个答案:

答案 0 :(得分:1)

我认为您必须测试None是这种情况:

| NOP3 value? {print("nada" if $value is None else $value.ret)}

或类似的内容:

| NOP3 v=value? {print("nada" if $v is None else $v.ret)}

甚至类似的方法也可以工作:

| NOP3 (value {print($value.ret)} | {print("nada")})

(假设您要嵌入Python代码)

但是,我强烈建议在语法中嵌入目标特定的代码:最好在侦听器或访问者中完成。