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 -~----------~----~----~----~------~----~------~--~---
