简体   繁体   English

PLY YACC pythonic语法用于累积逗号分隔值列表

[英]PLY YACC pythonic syntax for accumulating list of comma-separated values

I'm using YACC for the first time and getting used to using BNF grammar. 我第一次使用YACC并习惯使用BNF语法。

I'm currently building a list of type s from a comma separated list (eg. int , float , string ): 我目前正在建立一个listtype从一个逗号分隔的列表S(例如, intfloatstring ):

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. 规则有效,但我感觉我的p_type_list逻辑有点p_type_list ,可以简化为单行。

I haven't found any PLY specific examples of this online. 我没有在网上找到任何PLY特定的例子。 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. 这避免了列表副本。

Or "simplify" p_type_list to (you reduce by 1 line of code, not sure if that's worth it): 或者“简化” p_type_list (你减少1行代码,不确定是否值得):

def p_type_list(p):
    '''type_list : type
                 | type_list COMMA type'''
    if len(p) == 2:
       p[0] = [p[1]]
    else:
       p[0] = p[1] + [p[3]]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM