Search code examples
pythonyaccply

How to store errors in PLY yacc


I am using ply.yacc for building a parser, and I'm interesting in storing all syntax errors in a list. I want something like this:

parser = yacc.yacc()
parser.errors = []
parser.parse(program)
print(parser.errors) # do something with parser.errors

The problem is that when I define the rule for handling error

def p_error(p):
    ...

I don't how to access the parser instance, so I can append the error to my list. For the lexer, I used ply.lex and solved this problem because the token t which is passed as argument in the rule definition has a reference to the lexer.

def t_error(t):
  t.lexer.error.append(LexicographicError(t.lineno, t.value[0]))

Is there any way to do something similar with yacc parser???


Solution

  • The argument to p_error is usually a token (so the prototype would be better written def p_error(t):), so you could add the errors to the same list as you used in your lexer. But that's not ideal; first, because that's an odd place to keep the errors (both lexical and syntactical), and second because sometimes the argument to p_error is None (when the error occurs at the end of input).

    A better solution is to make the parser a class rather than a global, which is explained rather briefly in the Ply documentation (mostly by reference to the section on making the lexer a class). Normally, you would build the parser in the Parser class's __init__ method, saving it as self.parser. Then all of the p_* member functions take a self argument, as with any class function, and you can store the error list as a member attribute. (You can get at the parser using self.parser but I think keeping the list of errors in the object instance itself is cleaner than adding it to the parser instance.)