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
           ;
Другие вопросы по тегам