Тацу: Как проверить / обработать арифметические c подобные выражения в действиях semanti c - PullRequest
0 голосов
/ 06 февраля 2020

У меня есть грамматика TatSu, где я анализирую арифметику c выражения типа SignalGroup {ABUS='A3 + A2 + A1 + A0';}.

Соответствующая грамматика:

#--------------------------------------------- SIGNAL GROUPS BLOCK -----------------------------------------------------
signal_groups_block::SignalGroups
    =
    'SignalGroups' ~ [id:identifier] '{' ~ objs:{signal_group | annotation | udb} '}'
    ;
signal_group::SignalGroup
    =
    id:identifier '=' expr:signal_reference_expr ( ';' |
                                                   ('{' ~ attr:{signal_statement | annotation |udb} '}') )
    ;
signal_reference_expr
    =
    signal_name_array_opt
    | "'" ~ exprs:signal_reference_expr_items "'"
    ;
signal_reference_expr_items
    =
    left:signal_reference_expr_items op:'+' ~ right:signal_reference_expr_item
    | left:signal_reference_expr_items op:'-' ~ right:signal_reference_expr_item
    | left:signal_reference_expr_item
    ;
signal_reference_expr_item
    =
    '(' ~ @:signal_reference_expr_items ')'
    | signal_name_array_opt
    ;
signal_name_array_opt
    =
    id:identifier ['[' ~ msb:integer ['..' ~ lsb:integer] ']']
    ;

Выход AST:

{
  "objs": [
    {
      "__class__": "SignalGroup",
      "expr": {
        "exprs": {
          "left": {
            "left": {
              "left": {
                "left": {
                  "id": "A3",
                  "lsb": null,
                  "msb": null
                },
                "op": null,
                "right": null
              },
              "op": "+",
              "right": {
                "id": "A2",
                "lsb": null,
                "msb": null
              }
            },
            "op": "+",
            "right": {
              "id": "A1",
              "lsb": null,
              "msb": null
            }
          },
          "op": "+",
          "right": {
            "id": "A0",
            "lsb": null,
            "msb": null
          }
        }
      },
      "attr": null,
      "id": "ABUS"
    }
  ],
  "id": null
}

Я хотел бы сделать несколько проверок semanti c для этого правила. То есть проверьте, чтобы сигналы A3-A0 были объявлены в каком-то другом (сигнальном) блоке. Если не объявлено, поднять ошибку. Я сохранил таблицу имен (символов) всех сигналов для поиска при анализе другого (сигнального) блока. Я хотел бы знать, как лучше всего обходить такой AST в коде действия semanti c, поскольку он может быть очень глубоким, если мое выражение содержит, скажем, 200 сигналов (то есть A0 + A1 + .. A199). Прямо сейчас у меня есть только функция заглушки, вот так:

class STILSemantics(ModelBuilderSemantics):

    ....

    def signal_groups_block(self, ast, node):
    """Signal groups block."""

      log.info('Parse %s block', node)
      print('got here')
      from tatsu.util import asjsons
      print(asjsons(ast))

      # TODO: HOW TO WALK THE AST HERE????

      return ast

Я проверил TatSu do c и есть раздел на Walking Models, но кажется, что это только ПОСЛЕ полная модель АСТ построена. Может я не прав. Есть ли способ эффективно пройти AST блока signal_groups_block внутри правила проверки c семанти, пока строится вся модель (верхнего уровня)?

Ссылка: https://tatsu.readthedocs.io/en/stable/models.html#walking -модели

1 Ответ

1 голос
/ 14 февраля 2020

Для проверки предопределенных идентификаторов во время анализа вам нужна таблица символов .

Вы добавляете символы в таблицу в семантике для грамматических предложений, в которых они определены, и обращаетесь к таблице символов в семантике для грамматических предложений, в которых они используются.

Потому что TatSu сохраняет полную информацию для исходного ввода, может быть проще проверить эту семантику после анализа, используя walker . Сообщения об ошибках могут быть точными в строке с номером столбца, и пользователи обычно не обращают внимания на то, что сначала сообщается об ошибках syntacti c, а потом об ошибках semanti c, потому что анализаторы TatSu обычно останавливаются при первой ошибке (есть поддержка для восстановления синтаксического анализа в Тацу, но это недокументировано).

Таблицы символов на этапе синтаксического анализа необходимы только на языках, на которых токен может или может не быть ключевым словом в зависимости от контекста (да, PEG может обрабатывать некоторые контекстно-зависимые случаи с помощью semanti c действий).

...