PLY YACC синтаксический анализ IF-ELSE IF-ELSE вложенных операторов
Может ли кто-нибудь помочь мне с написанием правильных правил грамматики для вложенных операторов if? На моем языке я могу написать такие конструкции:
(IF CONDITION)
some statements
(IF CONDITION)
some statements
(ELSE IF CONDITION)
some statements
(ELSE IF CONDITION)
some statements
(ELSE IF CONDITION)
some statements
(ELSE)
some statements
(END)
some statements
(ELSE IF CONDITION)
some statements
(ELSE)
some statements
(END)
Я написал лексер, чтобы левая и правая скобки были RULE_OPEN
а также RULE_CLOSE
токены, "ЕСЛИ" IF
токен "END" END
маркер "ELSE" ELSE
маркер "СОСТОЯНИЕ" CONDITION
маркер.
Предположим, что "некоторые утверждения" могут быть чем угодно, что разрешено в моем языке (например, в обычном языке программирования). Важно, что возможно вкладывать операторы IF, возможно, бесконечно.
Надеюсь, что это понятно, пожалуйста, дайте мне знать, если я объяснил это плохо.
Неважно, как я пытаюсь. Я всегда получаю сдвиг / уменьшение конфликтов, и парсер не принимает правильный ввод.
Несмотря на то, что я успешно написал правила без использования if-if. Когда я добавляю правила для else-if, код для меня становится очень сложным.
Ниже мой успешный подход без части else-if (я перечислил только соответствующие правила):
statements: statement
statements: statements statement
statement: code
| data_out
| rule
rule: inline_if_statement
| block_if_statement
block_if_statement: RULE_OPEN IF CONDITION RULE_CLOSE statements RULE_OPEN END RULE_CLOSE
block_if_statement: RULE_OPEN IF CONDITION RULE_CLOSE statements block_else_statement
block_else_statement: RULE_OPEN ELSE RULE_CLOSE statements RULE_OPEN END RULE_CLOSE
block_else_statement: empty
empty :
Я думаю, что это очень распространенная проблема при разборе, и я надеюсь, что кто-то здесь уже решил ее:-) Спасибо за помощь!
1 ответ
Как правило, допускается единственный конфликт с уменьшением смещения для языка, в котором есть необязательное предложение ELSE. Пит Джинкс предлагает несколько альтернативных формулировок, которые могут разрешить конфликт.
Стратегия для определения конструкций ELSE-IF: трактуйте это как любой другой рекурсивно определенный повторяющийся блок:
running_else_if_statement : RULE_OPEN IF CONDITION RULE_CLOSE statements else_if_blocks
RULE_OPEN ELSE RULE_CLOSE statements RULE_OPEN END RULE_CLOSE
;
else_if_blocks : else_if_block
| else_if_blocks else_if_block
;
else_if_block : RULE_OPEN ELSE_IF CONDITION RULE_CLOSE statements
;
Как примечание к стилю: большинство практиков последовательно комбинируют все альтернативы для производства с трубами, как вы это делали с
statement : code
| data_out
| rule
;
Это сбивает с толку читать:
statements : statement
;
statements : statements statement
;
Большинство предпочитают:
statements : statement
| statements statement
;