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" - это токен IF, "END" - это токен END, "ELSE" - это токен ELSE, "УСЛОВИЕ" - это токен CONDITION.

Предположим, что «некоторые операторы» могут быть чем угодно, что разрешено в моем языке (например, в обычном языке программирования). Важно, что можно бесконечно вкладывать операторы IF.

Надеюсь, это понятно, пожалуйста, дайте мне знать, если я плохо объяснил.

Как бы я ни старался. Я всегда получаю конфликты сдвига/уменьшения, и синтаксический анализатор не принимает правильный ввод.

Несмотря на это, я успешно написал правила без else-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 : 

Я думаю, что это очень распространенная проблема при разборе, и я надеюсь, что кто-то здесь уже решил ее :-) Спасибо за помощь!


person JoshuaBoshi    schedule 12.07.2012    source источник


Ответы (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
           ;
person David Gorsline    schedule 12.07.2012
comment
Большое спасибо за ответ и ссылку на ресурс. Это мне очень помогло. - person JoshuaBoshi; 16.07.2012
comment
Как бы вы добились этого, используя только пробелы для встраивания блоков кода: пример if expression \n return this \n else \n return that - person Steve Peak; 10.12.2013
comment
@StevePeak Думаю, вам стоит проверить эту ссылку stackoverflow.com/questions/9420400/ - person JoshuaBoshi; 11.12.2013