For review: PEP 308 - If-then-else expression

holger krekel pyth at devel.trillke.net
Mon Feb 10 10:17:16 EST 2003


Andrew Koenig wrote:
> Roman> In Python, expression is a standalone statement. So in case of 
> 
> Roman> if expr1: expr2 else: expr3
> 
> Roman> the parser will notice the difference only at "else".
> 
> Here is how I am proposing to change the grammar to avoid that problem.
> Note that I have not run this grammar through a parser generator;
> nevertheless, I think the idea behind it is pretty clear.
> 
> Original:
> 
> expression ::= 
>              or_test | lambda_form
> 
> expression_stmt ::= 
>              expression_list
> 
> expression_list ::= 
>              expression ( "," expression )* [","]
> 
> Proposed:
> 
> uncond_expression ::= 
>              or_test | lambda_form
> 
> expression ::=
> 	     uncond_expression | if_form
> 
> if_form ::=
> 	     "if" expression ":" expression
> 	     ( "elif" expression ":" expression)*
> 	     "else" ":" expression
> 
> expression_stmt ::=
> 	     uncond_expression ( "," expression )* [","]

You are not targeting the real problem, i think. Quoting from 
Python-2.2.2/Grammar/Grammar

    stmt: simple_stmt | compound_stmt    

    compound_stmt: if_stmt | while_stmt | for_stmt | ...

    simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE

    small_stmt: expr_stmt | print_stmt  | del_stmt | ...

Your "expression -> if_form" path would have to be followed
for the next tokens and then the parser might need to backtrack 
to recognize that this rather the "if_stmt". Or the other
way round.  Either way the parser needs lookahead. 
I don't see a way how to get around this without some more
special casing.

Good news is that experimenting with Python's grammar is 
dead-easy.  Modify Python's Grammar/Grammar file and run "make"
(after the configure-dance which you need to do before doing 
anything). 

At some point you will probably see "ambiguity" warnings (they
don't abort the compile-process, watch out).  

If i were you, i would try to 

a) special case the 'if_stmt'

b) disallow expr_stmt to contain a ternary

c) otherwise allow your ternary in expressions

Pretty tricky <wink> but not outright impossible. 

    holger





More information about the Python-list mailing list