I’ve tried to search around for the answer to this question, but can’t seem to find one.
I’m trying to write a parser in Python using PLY for a made up language. A simplified version of my BNF looks like this:
statement-list -> statement ',' statement-list |
'print' expr
statement -> ident 'was' 'a' type |
ident 'became' expr
type -> 'number' | 'letter'
expr -> factor |
expr '+' factor |
expr '-' factor
factor -> number | letter | ident
where number and letter are like int and char.
The Yacc documentation (http://www.dabeaz.com/ply/ply.html#ply_nn23) only shows the syntax for simple arithmetic expressions where it’s clear what p[0] should be.
def p_expression_plus(p):
'expression : expression PLUS term'
p[0] = p[1] + p[3]
My question is what do I do for statement-list in my BNF? I’ve got:
def p_statement_list_comma(p):
'statement-list : statement COMMA statement-list'
but I’m really not sure what to put next.
Any help would be very much appreciated!
It really depends on how you structure your code and how you want to evaluate it. If you are evaluating as you go along, provided it evaluates in the right order, you don’t want you probably don’t want anything after the docstring of
p_statement_list_commai.e. just like how you had it – the statements will be evaluated anyway, and if needed you can keep a global dictionary of variables or something similar to keep track of some state such as identifier values.If you want to build up a parse tree e.g. for evaluation separately if you don’t like ply’s order of evaluation, you might do something like this:
This would then give you a list of statements, with the last element in the list being an expression. This uses lists for simplicity; you can use your own classes too if you want – just assign whatever python object you want to p[0] and it will be available to the level above.
If you want the result of the print expression being returned from yacc.parse (the value from the top level of the parse tree will be returned from yacc.parse), you might do it like this: