2013-04-18 2 views
2

Прошу прощения за мой основной вопрос, но я действительно борется здесь. Мне нужно сделать рекурсивный парсер. Я работаю на Python и использую PLY. Моя грамматика следующая:Рекурсивный спуск Parser с использованием Python и PLY

< список> → (< sequence>) |()

< последовательность> < listelement>, < последовательность> | < listelement>

< listelement> < лист> | НОМЕР

Будет ли это выглядеть примерно так? Я в отъезде? Конечная цель - прочитать список в структуре данных и затем распечатать его.

 
def p_list(p) 
    'list : "("sequence")" | "("")"' 

def p_sequence(p) 
    'sequence : list_el","sequence | list_el' 

def p_list_el(p) 
    'list_el : list | NUMBER' 

Если бы кто-нибудь задавался вопросом, каким будет полное решение, я отправлю его в ближайшее время.

+0

Нужно ли NUMBER определять или это специальное определение в PYR? – Patashu

+1

Что такое PYR? Вы имеете в виду PLY? – georg

+0

Я не могу найти этот предполагаемый PYR с Google. Ссылка на то, где вы его получили, будет полезна. Хотя на основе того, что я вижу, действительно похоже, что вы действительно имеете в виду PLY. –

ответ

4

Это, как я хотел бы сделать это:

tokens = ("LBRACKET", "RBRACKET", 
      "INTEGER", "FLOAT", "COMMA") # So we can add other tokens 
t_LBRACKET = r'\(' 
t_RBRACKET = r'\)' 
t_INTEGER = r'\d+' 
t_FLOAT = r'\d+\.\d+' 
t_COMMA = r',' 

def p_list(p): 
    """list : LBRACKET sequence RBRACKET 
      | LBRACKET RBRACKET""" 
    if len(p) == 4: 
     p[0] = p[2] 
    else: 
     p[0] = None 

def p_number(p): 
    """number : INTEGER 
       | FLOAT""" 
    p[0] = p[1] 

def p_sequence(p): 
    """sequence : list_el COMMA sequence 
       | list_el""" 
    if len(p) == 4: 
     p[0] = p[1] + p[3] 
    else: 
     p[0] = p[1]   

def p_list_el(p): 
    """list_el : number 
       | list""" 
    p[0] = p[1] 

Edit:
Краткое объяснение дополнительных лексем: Все в сценарии должны в конечном счете сводятся к токен или символ, который вы определили (So это законно добавить). Указав их все в качестве токенов, их легче читать и работать.

+0

Я просто собирался прокомментировать «COMMA», но я вижу, что вы добавили его сейчас. Отличная работа! – jszakmeister

+0

Да, я сначала пропустил запятую в оригинальном посте. К сожалению! – TyrantWave

+0

это очень полезно. Я следую почти всему этому. Мой единственный вопрос - почему вы проверяете len (p) == 4? Разве это не должно быть в len (p) == 3 в обоих случаях ((LBRACKET sequence RBRACKET) или (list_el COMMA sequence))? – Ryan

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