2013-11-25 2 views
0

Я использую OMeta и Python Parsley (http://parsley.readthedocs.org/) для разбора. Есть ли способ доступа к строке, соответствующей конкретному правилу?Как я могу получить доступ ко всей согласованной строке в Python Parsley?

Например, рассмотрим следующий код:

In [1]: import parsley 
In [2]: g = parsley.makeGrammar('addr = <digit+>:num ws <anything+>:street -> {"num": num, "street": street}', {}) 
In [3]: g('15032 La Cuarta St.').addr() 
Out[3]: {'num': '15032', 'street': 'La Cuarta St.'} 

Я ищу способ сослаться на весь матч, чтобы вернуть что-то вроде:

{'match': '15032 La Cuarta St.', 'num': '15032', 'street': 'La Cuarta St.'} 

Следующий код работает для этой цели:

g = parsley.makeGrammar('addr = <<digit+>:num ws <anything+>:street>:match -> {"num": num, "street": street, "match": match}', {}) 

Однако у меня есть сотни правил, и я бы хотел избежать обертывания каждого из них.

+0

Не критика, но больше для моего понимания вашего вопроса, но почему вы используете Python Петрушку вместо регулярных выражений? –

+0

Regexps гораздо сложнее построить и поддерживать сложные структуры. (Мой фактический пример использования - синтаксический анализ текстовых представлений геномных вариантов.) Пожалуйста, посмотрите на документы Parsley для примеров. – Reece

+0

Понял. Петрушка выглядит великолепным модулем, и я с удовольствием узнал об этом. Похоже, нет простой альтернативы предложенному вами методу. Является ли ваше единственным приемлемым решением не изменять правила грамматики абсолютно? –

ответ

0

Вот как бы я это сделал, если бы не хотел изменять многие правила вручную. Он использует ваше решение, но не требует ручного редактирования правил. Вы можете обезвредить это, если вы посмотрите на источник https://github.com/python-parsley/parsley/blob/master/parsley.py, тогда вам даже не придется добавлять вызов в myMakeGrammar.

import parsley 
import re 

prog = re.compile('([a-z]* =) (.*) -> {(.*)}') 

def myMakeGrammar(grammar): 
    gs = prog.search('addr = <digit+>:num ws <anything+>:street -> {"num": num, "street": street}') 
    new_grammar = gs.group(1) + '<' + gs.group(2) + '>:match -> {' + gs.group(3) + ',"match": match}' 

return new_grammar 

g = parsley.makeGrammar(myMakeGrammar('addr = <digit+>:num ws <anything+>:street -> {"num": num, "street": street}'), {}) 
print g('15032 La Cuarta St.').addr() 

Это возвращает,

{'num': '15032', 'street': 'La Cuarta St.', 'match': '15032 La Cuarta St.'}