Thanks for the prompt and verbose reply!
It seems to work, but if I understand correctly, it still activates the rule
var_list even for things which should be expr_list, but "inside" an
expr_list. So in order to act by that rule, I'll have to return it and see
if it goes to an assign or an expr_list?
Messy...

"var_list appears before expr_list in the grammar"
How can I know that? And how can I affect that? (for any two given rules)

Thanks again,
  Erez.

On Wed, Jun 10, 2009 at 8:55 PM, Bruce Frederiksen <[email protected]>wrote:

>  Hi Erez,
>
> There is an ambiguity between var_list and expr_list.  So when ply has seen
> "a, b = c" it could reduce the last 'c' to either var_list or expr_list.  It
> will pick var_list because var_list appears before expr_list in the
> grammar.  This prevents the use of the rule "assign_list : var_list ASSIGN
> expr_list" in that case.
>
> It works for "a,b=1,2" because "1" can only be an expr.
>
> You should be able to fix this by allowing var_list to be a type of
> expr_list.  Perhaps something like:
>
> expr_list: var_list
>               | var_list COMMA expr2_list
>               | expr2
>               | expr2 COMMA expr_list
>
> add expr2 to be any expr except NAME, and expr2_list starts with an expr2,
> then any expr after that:
>
> expr: NAME
>        | expr2
>
> expr2: expr PLUS expr
>          | NUMBER
>
> expr2_list: expr2
>                 | expr2 COMMA expr_list   # expr_list, not expr2_list, to
> allow any expr after the first non-NAME
>
> Now ply isn't forced to decide between two interpretations of what 'c' is
> in "a,b=c,d".  Ply doesn't have to decide until it has "c,d"; which could
> either be a var_list or an expr_list.  It will decide this depending on the
> next token.  If the token is, say, PLUS, then 'c,d' will end up an expr_list
> (expr_list: var_list COMMA expr2_list, where expr2_list: expr2, and expr2:
> expr PLUS expr).  If it's ASSIGN, it must be a var_list.
>
> This should get you closer.
>
> -bruce
>
>
> Erez wrote:
>
> Hello dear plyers,
> Please help me solve a little ambiguity!
>
> I've been trying to write a parser for python for my personal
> enjoyment. I'm aware that it's hard.
> As you probably know, Python's assignment is rather complex. You can
> use multiple assignments on one line, in two forms:
> 1)  a=b=c=d=4
> 2) a,b=3,4
>
> I wrote a syntax for it (which I added, in minimal form, to the bottom
> of this message), and it seems okay.
> It can even parse statements like: "c,d=x,y=a+b"
> However, it fails to parse "c,d=a,b"
> My guess is that PLY thinks it's getting another variable declaration,
> and cannot back down from this assumption.
>
> I tried for several days and cannot get all forms to work.
> Perhaps I'm doing something wrong (or not doing it sufficiently
> right :) )
> I would really appreciate pointers.
>
>
> Here is the script:
> #---------------------------------------
> tokens = (
>     'NAME','NUMBER',
>     'PLUS','ASSIGN', 'COMMA', 'NL'
>     )
>
> # Tokens
> t_PLUS    = r'\+'
> t_COMMA  = r','
> t_ASSIGN  = r'='
> t_NAME    = r'[a-zA-Z_][a-zA-Z0-9_]*'
> t_NUMBER = r'\d+'
>
>
> # Ignored characters
> t_ignore = " \t"
> #t_NL = r'\n+'
>
> def t_NL(t):
>     r'\n+'
>     t.lexer.lineno += t.value.count("\n")
>     return t
>
> def t_error(t):
>     print "Illegal character '%s'" % t.value[0]
>     t.lexer.skip(1)
>
> # Build the lexer
> import ply.lex as lex
> lex.lex()
>
> # Parsing rules
>
> def p_statements(t):
>     '''statements : statement
>                   | statement statements
>     '''
>     t[0] = t[1:]
>
> def p_statement(t):
>     '''statement : assign_list NL
>                  | NL
>     '''
>     t[0] = t[1:]
>
> def p_assign_list(t):
>     """assign_list : var_list ASSIGN expr_list
>                    | var_list ASSIGN assign_list
>     """
>     t[0] = t[1:]
>
> def p_var_list(t):
>     """var_list : NAME
>                 | NAME COMMA var_list
>     """
>     t[0] = ['var_list'] + t[1:]
>
> def p_expr_list(t):
>     """expr_list : expr
>                  | expr COMMA expr_list
>     """
>     t[0] = ['expr_list'] + t[1:]
>
> def p_expr(t):
>     """expr : NAME
>             | expr PLUS expr
>             | NUMBER
>     """
>     t[0] = t[1:]
>
> def p_error(t):
>     if t:
>         print "Syntax error at '%s'" % t.value, t.lineno, t.lexpos
>
> import ply.yacc as yacc
> yacc.yacc()
>
> print yacc.parse("""
> c,d=x,y=a+b
> c,d=1,2
> c,d=a,b
> """)
> # first two work, but last throws an exception!
>
>
> #--------------------------------------- END OF SCRIPT
>
> Thanks,
>   Erez
>
>
>
>
>
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"ply-hack" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/ply-hack?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to