I'm using YACC for the first time and getting used to using BNF grammar.
I'm currently building a list
of type
s from a comma separated list (eg. int
, float
, string
):
def p_type(p):
'''type : primitive_type
| array
| generic_type
| ID'''
p[0] = p[1]
def p_type_list(p):
'''type_list : type
| type COMMA type_list'''
if not isinstance(p[0], list):
p[0] = list()
p[0].append(p[1])
if len(p) == 4:
p[0] += p[3]
The rules work, but I'm getting the sense that my p_type_list
logic is a bit of a kludge and could be simplified into a one-liner.
I haven't found any PLY specific examples of this online. Any help would be greatly appreciated!
There are two productions. Use two separate functions. (There is no extra cost :-) )
def p_type_list_1(p):
'''type_list : type'''
p[0] = [p[1]]
def p_type_list_2(p):
'''type_list : type_list COMMA type'''
p[0] = p[1] + [p[3]]
Note: I fixed your grammar to use left-recursion. With bottom-up parsing, left-recursion is almost always what you want, because it avoids unnecessary parser stack usage, and more importantly because it often simplifies actions. In this case, I could have written the second function as:
def p_type_list_2(p):
'''type_list : type_list COMMA type'''
p[0] = p[1]
p[0] += [p[3]]
which avoids a list copy.