Как мне обработать отрицательные числа в грамматике PEG?

Я пытаюсь написать простой синтаксический анализатор выражений int, используя tatsu, генератор синтаксических анализаторов Python на основе PEG. Вот мой код:

import tatsu

grammar = r'''
    start = expression $ ;
    expression = add | sub | term ;
    add = expression '+' term ;
    sub = expression '-' term ;
    term = mul | div | number ;
    mul = term '*' number ;
    div = term '/' number ;
    number = [ '-' ] /\d+/ ;
'''
parser = tatsu.compile(grammar)
print(parser.parse('2-1'))

Выход этой программы ['-', '1'] вместо ожидаемого ['2', '-', '1'],

Я получаю правильный вывод, если я либо:

  • Убрать поддержку унарного минуса, т.е. поменять последнее правило на number = /\d+/ ;
  • Удалить термин, правила mul и div и поддерживать только сложение и вычитание
  • Заменить второе правило на expresssion = add | sub | mul | div | number ;

Последний вариант на самом деле работает, не оставляя никакой функции, но я не понимаю, почему она работает. Что здесь происходит?

РЕДАКТИРОВАТЬ: Если я просто перевернуть правила add/sub/mul/div, чтобы избавиться от левой рекурсии, это также работает. Но тогда оценка выражений становится проблемой, так как дерево разбора переворачивается. (3-2-1 становится 3-(2-1))

1 ответ

Существуют левые случаи рекурсии, которые TatSu не обрабатывает, и работа над исправлением которых в данный момент приостановлена.

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

Другие вопросы по тегам