tl; dr:如何从语法动作中引用可选规则rulename?
?
我尝试了此操作,显然是失败的,因为 $ value 是
None
(null)当value
规则不匹配时,并且访问null引用的属性给出了错误:
| NOP3 value? {print( $value.ret )}
然后我尝试了此操作,但是现在我得到了我无法引用Rulecontext $ value 本身的错误,但我必须引用其属性之一:( error(67):在$ value 中缺少属性访问属性)
| NOP3 value? {print( $value.ret if $value is not None else "empty" )}
我能够使其与此肮脏的解决方法一起使用,该解决方案会注入自定义的骇客代码,该代码插入if wht frule value 不匹配时触发的其他条款,但它很丑陋,我猜想应该有更好的解决方案:
| 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?
成为子规则,并将动作嵌入其中,而不是父级规则。
我认为您必须对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代码)
但是,我强烈建议不是在您的语法中嵌入特定代码:最好在听众或访客中完成。