Re: [PHP-DEV] Re: Bug #838 Updated: Parser error in nested if From: Zeev Suraski (bourbon <email protected>)
Date: 10/09/98

At 15:47 09/10/98 +0200, Antonio Garcia Mari wrote:
>> How is it clear? Because you've indented it that way? :)
>> It's not clear at all, and in fact, the solution for the dangling else
>> shift/reduce problem clearly states that the else belongs to the closest
>> IF.
>
>It's clear because gramatically speaking, its clear that a colon elseif
>must belong to a colon if and a non colon elseif cannot belong to a
>colon if. The parser is applying this last rule when it doesn't accept
>this:
>if ($b==2): print "a=2 b=2<br>";
>else print "a=3";
>endif;
>(note that i left identing :-)
>> PHP makes no distinction between if's with braces, no braces, or colons,
>> and it doesn't pay attention to your indentation either. As soon as it
>> sees the elseif, it expects it to match the inner IF sentence, and since
>> it doesn't, it fails.
>
>In my point of view, PHP it's making distinction between colon if's and non
>colon if's all the time when validating the sintaxis.
>The only moment when it isn't is when it expects an else to match the
>inner IF sentence.
>
>A colon else must match the inner block if sentence.
>
>Ok, you can say that's difficult to implement, but it's clear.

Nope, it's not clear at all, and it's impossible to implement using an LALR
parser. Why is it not 'clear'? Because compilers aren't human beings and
can't apply intelligence. The parser has a working set of rules, with
rules of what to do in each case, using one lookahead token at the most.

We've designed the language to use the standard solution for the dangling
else problem, which means that an else (or an elseif) applies to the least
recently nested if. When the parser spots an else statement, it expects it
to match the least recently nested if. It doesn't scan the whole block and
tries to make sense out of it. Of course, you could do that, but it
wouldn't have been an LALR parser and it would have been slower by orders
of magnitude (all popular languages can be described by LALR grammars,
including C, Perl, Java and just about anything else you can think of). It
expects you to follow the language grammar, and an else (or elseif) at that
spot is supposed to match that last if. Because of that, it expects that
else to have the same syntax as the last if, i.e., if the last if wasn't
using colon mode, the else shouldn't either. Since that's not the case, it
results in a parse error.

Zeev

--
Zeev Suraski   <zeev <email protected>>
For a PGP public key, finger bourbon <email protected>

-- PHP Development Mailing List http://www.php.net/ To unsubscribe send an empty message to php-dev-unsubscribe <email protected> For help: php-dev-help <email protected>