От this question, грамматика для выражений, включающих бинарные операторы (+ - * /), который запрещает внешние скобки:Можно ли написать рекурсивный спуск парсер для этой грамматики?
top_level : expression PLUS term
| expression MINUS term
| term TIMES factor
| term DIVIDE factor
| NUMBER
expression : expression PLUS term
| expression MINUS term
| term
term : term TIMES factor
| term DIVIDE factor
| factor
factor : NUMBER
| LPAREN expression RPAREN
Эта грамматика LALR (1). Поэтому я смог использовать PLY (реализация на Python yacc) для создания анализатора восходящего потока для грамматики.
Для сравнения, теперь я хотел бы попытаться создать парсер для рекурсивного спуска сверху вниз для одного и того же языка. Я преобразовал грамматику, удаляя левую рекурсию и применяя влево-факторинг:
top_level : expression top_level1
| term top_level2
| NUMBER
top_level1 : PLUS term
| MINUS term
top_level2 : TIMES factor
| DIVIDE factor
expression : term expression1
expression1 : PLUS term expression1
| MINUS term expression1
| empty
term : factor term1
term1 : TIMES factor term1
| DIVIDE factor term1
| empty
factor : NUMBER
| LPAREN expression RPAREN
Без top_level
правила эта грамматика LL (1), так что написание рекурсивным спуском анализатор может быть довольно простым. К сожалению, в том числе top_level
, грамматика не LL (1).
- Существует ли классификация «LL» для этой грамматики (например, LL (k), LL (*))?
- Можно ли написать парсер для рекурсивного спуска для этой грамматики? Как это будет сделано? (Требуется ли откат?)
- Возможно ли упростить эту грамматику, чтобы облегчить подход рекурсивного спуска?
+1 для замечания об использовании LL (1), когда легко найти сильные генераторы парсера. Зачем покупать лишнюю головную боль? –
Существует еще один простой способ отклонить (....) на основе наблюдения, что любая полезная грамматика для языка должна принимать хотя бы этот язык и может принимать больше (трудно быть совершенным). Итак, что мы обычно делаем с синтаксическим анализатором, это «принимать (слегка) слишком много и отклонять избыток» (используя некоторые механизмы вне парсера). Отказаться от синтаксического анализа (....) теперь легко: проанализировать с помощью простой грамматики, которая позволяет это, и отклонить любой синтаксический анализ, который имеет (...) на верхнем уровне. –
@ IraBaxter: Да, я подумал об этом, но формальная грамматика была достаточно простой, и код для RDP с ручным управлением в конечном итоге был бы очень похож на то, что у вас получилось бы с помощью стратегии отклонения. (IMHO, вам понадобится довольно веская причина запретить внешние круглые скобки, чтобы оправдать время, отведенное для ответа на этот вопрос :)) – rici