2013-03-14 4 views
9

Я пытаюсь использовать indentedBlock в pyparsing (который выглядит потрясающе для меня), чтобы рассеять некоторые вложенные отступы, но я немного борюсь с пониманием его описания в ссылке API (или более конкретных примеров под http://pyparsing.wikispaces.com или упоминание в How do I parse indents and dedents with pyparsing?).Простая демонстрация использования indentBlock pyparsing в рекурсивном режиме

Может ли кто-нибудь указать мне краткую демонстрацию или объяснение того, как использовать indentedBlock рекурсивно или, может быть, предоставить ее здесь? Например, как бы мы преобразуем что-то YAMLish как ...

- a1_el 
    - b1_el 
     x1_attr: 1 
     x2_attr: 2 
    - b2_el 
     - c1_el # I am a comment 
    - b3_el 
     x1_attr: 1 

... в какой-то XML-представления, такие как ...

<a1_el> 
    <b1_el x1_attr="1" x2_attr="2"/> 
    <b2_el> 
     <c1_el/><!-- I am a comment --> 
    </b2_el> 
    <b3_el x1_attr="1"/> 
</a1_el> 

... с indentedBlock? (Также: В каких практических ситуациях мне нужны разные отпионы для параметра indentStack?). Большое спасибо!

ответ

6

Это немного старый, но вот частичный ответ:

from pyparsing import * 

COMMENT = pythonStyleComment 
OPCOMMENT = Optional(COMMENT) 
IDENT  = Word(alphas, alphanums + '_') 

attribute = IDENT + Suppress(':') + Word(alphanums) + OPCOMMENT 
element  = Suppress('-') + IDENT + OPCOMMENT 
elementBlock = Forward() 
blockContent = attribute|elementBlock|COMMENT 
elementBlock << element + Optional(indentedBlock(blockContent, [1])) 

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

Она демонстрирует использование indentedBlock так, чтобы сделать его коротким, это не позволяет комментариев за пределами дерева, и он будет принимать только один корневой элемент (не проблема для XML ...)

О indentStack: он хранит список текущего количества отступов, а последний элемент списка показывает текущий столбец отступа. Как указывается в документации, все высказывания в грамматике с вложенными блоками с использованием отступа должны иметь один и тот же список. Поскольку есть только один, я только что создал его прямо в вызове indentedBlock.

Я оставляю превращение результата в XML в качестве упражнения для читателя :-P

+0

Это кажется раздеться углублениями вниз красиво, и требует немного коды! (BTW: Если значение по умолчанию второго параметра «indentedBlock()» не может быть определено как «[1]»? Не ожидаем ли мы просто потребовать '[1]' в большинстве случаев? Почему люди часто кажутся явным образом определяю переменную 'indentstack' перед вызовом' indentedBlock() '?) – texb

+0

Ну, имея' indentstack' как отдельную переменную, вы можете отслеживать ее из кода разбора библиотеки. Кроме того, вы можете утверждать, что это «лучший программник». Но я знаю, как стек будет использоваться внутри (посмотрел бы в коде), поэтому я просто решил, что здесь не нужна переменная, и я передал ее прямо в качестве аргумента. Вы можете сделать, как вам угодно :) –

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