Как вы ссылаетесь на необязательное правило `rulename?` Внутри действия грамматики в Antlr4? - PullRequest
0 голосов
/ 19 февраля 2019

TL; DR: Как вы ссылаетесь на необязательное правило rulename? из грамматического действия?
Я попробовал это, и это, очевидно, не удалось, потому что $ value равно None (null), когда правило value не соответствует, а доступ к атрибуту нулевой ссылки выдает ошибку:

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

Затем я попробовал это, но теперь я получаю сообщение об ошибке, что я не могу ссылаться на сам RuleContext $ value , но я должен ссылаться на один из его атрибутов: ( error (67): отсутствует доступ к атрибуту для ссылочного значения правила в $ value )

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

Мне удалось заставить его работать с этим грязным обходным путем, который внедряет пользовательский хакерский код, который подключается к условию if, чье-то, если вызванокогда подправило значение не совпадает, но это некрасиво, и я думаю, что для этого должно быть лучшее решение:

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

Примечание: $ value.ret Возвращаемое значение подправила.

Редактировать: Итерация по Барт Киерс 'ответ:
Поскольку мне действительно ничего не нужно делать, если значение подправило не совпало, я смог упростить его следующим образом:

| NOP3 ( value {do_something()} )?  

Таким образом, по сути, сделал value? подправилом и внедрил в него действие вместо родительского правила.

1 Ответ

0 голосов
/ 19 февраля 2019

Я думаю, что вы должны проверить на 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)

Однако я настоятельно рекомендую не встраивать целевой код в вашу грамматику: это лучше сделать в слушателе или посетителе.

...