Как мне обработать отрицательные числа в грамматике 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 не обрабатывает, и работа над исправлением которых в данный момент приостановлена.
Вы можете использовать левый / правый оператор соединения / сбора для управления ассоциативностью анализируемых выражений в нерекурсивной грамматике.