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???
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.)