如何从 Antlr4 的语法操作中引用可选规则“rulename?”?

How do you reference an optional rule `rulename?` from within a grammar action in Antlr4?

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


我试过了,但显然失败了,因为当 value 规则不匹配时 $valueNone (null),并且访问空引用的属性会给出一个错误:

| 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 whose else 子句中,但是它很难看,我想应该有更好的解决方案:

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

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

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

| NOP3 ( value {do_something()} )?  

所以基本上使 value? 成为一个子规则并将操作嵌入其中,而不是父规则。

我认为你必须测试 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 代码)

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