2015-12-24 2 views
1

Я использую YACC в первый раз и привык к использованию грамматики BNF.PLY YACC pythonic синтаксис для накопления списка значений, разделенных запятыми

Я в настоящее время строит list из type сек из списка разделенных запятыми (например 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] 

правила работы, но я получаю чувство, что мой p_type_list логика - это немного клочья и может быть упрощена в однострочный.

Я не нашел никаких конкретных примеров этого онлайн. Любая помощь будет принята с благодарностью!

ответ

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

 Смежные вопросы

  • Нет связанных вопросов^_^