Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple demonstration of using pyparsing's indentedBlock recursively

I am trying to use indentedBlock in pyparsing (which looks awesome to me) to dissect some nested indentations, but am struggling a bit with comprehending its description in the API reference (or the more specific examples under http://pyparsing.wikispaces.com or the mentioning in How do I parse indents and dedents with pyparsing?).

Could someone please point me to a concise demonstration or explanation of how to use indentedBlock recursively, or maybe provide one here? E.g., how would we convert something YAMLish like...

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

...into some XML representation such as ...

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

...with indentedBlock? (Also: In what practical situations would I need the different otpions for the indentStack parameter?). Thanks a lot!

like image 681
texb Avatar asked Mar 14 '13 19:03

texb


1 Answers

This is a bit old, but here's a partial answer:

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

I've assumed that elements can contain both attributes and elements in arbitrary order. elementBlock will parse the whole tree.

It showcases the use of indentedBlock so, to make it short, it doesn't allow for comments outside the tree, and it will accept only one root element (not a problem for XML...)

About indentStack: it keeps a list of the current number of indented levels and the last element of the list shows the current indent column. As the documentation points out, all the statements on a grammar with nested blocks using indentation should share the same list. As there's only one, I've just created it straight in the call to indentedBlock.

I leave turning the result into XML as an exercise for the reader :-P

like image 189
Ricardo Cárdenes Avatar answered Oct 21 '22 01:10

Ricardo Cárdenes