2015-12-24 32 views
1

我第一次使用YACC並習慣於使用BNF語法。PLY YACC pythonic語法用於累積逗號分隔值列表

我目前正在從一個逗號分隔的列表(例如intfloatstring)建設typelist一個S:

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] 

規則的工作,但我得到這個意義上,我p_type_list邏輯有點混亂,可以簡化爲一行。

我還沒有找到任何這個在線PLY的具體例子。任何幫助將不勝感激!

回答

5

有兩個作品。使用兩個獨立的功能。 (沒有額外費用:-))

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]] 

注:我定你的語法使用左遞歸。使用自下而上的解析,左遞歸幾乎總是您想要的,因爲它避免了不必要的解析器堆棧使用,更重要的是因爲它經常簡化操作。在這種情況下,我可以寫第二個函數爲:

def p_type_list_2(p): 
    '''type_list : type_list COMMA type''' 
    p[0] = p[1] 
    p[0] += [p[3]] 

它避免了列表複製。

2

或「簡化」 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]]