if elsif else разбор оператора

я работал над компилятором для императивного языка, используя 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

block — это просто список операторов в квадратных скобках {}


person Alb3rt    schedule 06.02.2012    source источник
comment
Ознакомьтесь с этим синтаксическим анализатором IF-ELSE с использованием Flex и Bison c-madeeasy.blogspot.in/2012/05/   -  person techno    schedule 14.05.2012


Ответы (3)


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

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

person Rcl    schedule 06.02.2012
comment
это действительно приятно читать, теперь я могу спокойно начать работать над AST, спасибо! - person Alb3rt; 06.02.2012
comment
Это очень неполный ответ. Ответ Дервалла содержит более полезные рассуждения о том, почему конфликтов нет. - person Lii; 03.05.2013

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

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

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

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

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

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

person Dervall    schedule 06.02.2012
comment
С самого начала меня учили, что написание условных операторов, как в первом примере, является плохой практикой, поэтому я действительно не думал в этом конкретном случае, но я думаю, что это хорошо, заставляя программиста заключать все «вещи» внутри блок, спасибо за объяснение! - person Alb3rt; 06.02.2012
comment
Вы имеете в виду «чужого»? Мне кажется, что синтаксис Alb3rt сильнее, но тогда я пришел из Ады, где эквивалент {} синтаксически необходим; и я всегда добавлял {}, если писал на C или подобном. - person Simon Wright; 26.02.2012
comment
Я имею в виду странность в контексте того, что нормально для разработчика фигурных скобок, который ожидает, что сможет опустить скобки для одного вкладыша. В обеих грамматиках нет ничего плохого. - person Dervall; 26.02.2012

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

%nonassoc XIF
%nonassoc ELSE

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

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

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

person Shou Ya    schedule 25.02.2012