если elsif еще разбор заявления - PullRequest
2 голосов
/ 06 февраля 2012

Я работал над компилятором для императивного языка, используя lex и yacc, и сегодня я закончил грамматику, дело в том, что я читал в Интернете, что каждая грамматика должна иметь несколько сдвигов / уменьшить конфликты, особенно если в нем есть операторы if / else, которые часто называют висячими if-else, а у меня есть операторы if / elsif / else, но при компиляции он не генерирует никакого конфликта, вопрос заключается в

¿означает ли это, что у этой грамматики есть недостатки только потому, что она не создает никаких сдвигов / сокращений конфликтов? У меня нет большого опыта, но я не могу найти никаких проблем с этим

В случае, если вам нужна дополнительная информация, выработка для операторов if / elsif / else в этой грамматике выглядит примерно так:

statement -> ... 
------------| initial_conditional_stmt

initial_conditional_stmt: conditional_stmt
-----------------------| conditional_stmt 'else' block


conditional_stmt -> 'if' '(' expression ')' block
------------------| conditional_stmt elsif  '(' expression ')' block

блок - это просто список операторов в скобках {}

Ответы [ 3 ]

3 голосов
/ 06 февраля 2012

Отсутствие сдвига / уменьшения конфликтов означает, что вы по-настоящему хорошо поработали над своим языковым дизайном, и это никогда не бывает двусмысленным.

Молодец, похлопайте себя по спине, расслабьтесь, идите, хватайте пиво из холодильника.

2 голосов
/ 06 февраля 2012

Причина, по которой вы не получаете здесь болтаться, заключается в том, что вы используете блок вместо обычного выражения.

Для вашей грамматики вы не можете сделать

if (cond)
    if (cond) {
        [stuff]
    }
    else
    {
    }    

Вы быдолжен сделать это

if (cond) 
{
    if (cond) {
        [stuff]
    }
    else
    {
    }   
}

Каждый вложенный оператор if должен быть внутри соответствия {}.Это в вашем случае устраняет висячие еще за счет немного более странного синтаксиса.По сравнению с «нормальной» грамматикой «блок» будет «оператором», который также может быть другим оператором «if», вызывая классический конфликт сдвига / уменьшения.

0 голосов
/ 25 февраля 2012

Вы можете использовать этот код следующим образом:

%nonassoc XIF
%nonassoc ELSE

   stmt: IF expr stmt %prec XIF
       | IF expr stmt ELSE stmt

Это способ изменить конфликт приоритетов между if и else.

Надеюсь, это поможет.

...