3
votes

i've been working on a compiler for an imperative language using lex and yacc, and today i finished the grammar, the thing is that i've been reading on the web that every grammar is expected to have a few shift/reduce conflicts, specially if it has if/else statements, that's often known as dangling if-else, and mine does have if/elsif/else statements yet it doesn't throw any conflict when compiled, the question is

¿does that means this grammar has flaws just because it doesn't throw any shift/reduce conflicts? i dont have much experience doing this but i can't find any problem with it

In case you want some more information the productions for the if/elsif/else statements in this grammar are something like this:

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

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


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

block is just a list of statements inside brackets {}

3
Check out this IF-ELSE Parser using Flex and Bison c-madeeasy.blogspot.in/2012/05/…techno

3 Answers

3
votes

No shift/reduce conflicts means you did a really good job of your language design and it's never ambiguous.

Well done, give yourself a pat on the back, relax, go grab a beer from the fridge.

2
votes

The reason you are not getting the dangling else here is because you're using a block instead of the normal statement.

For your grammar you cannot do

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

You would have to do this

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

Every nested if statement must be inside matching { }. This in your case eliminates the dangling else at the expense of a bit stranger syntax. Compared to a "normal" grammar "block" would be "statement" which could also be another if statement, thus causing the classical shift/reduce conflict.

0
votes

You may better to use these code as following:

%nonassoc XIF
%nonassoc ELSE

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

That is a way to change precedence conflict between if and else.

Hope it helps.