Skip to content Skip to sidebar Skip to footer

Pyparsing: Grammar For List Of Dictionaries (erlang)

I'm trying to build a grammar to parse an Erlang tagged tuple list, and map this to a Dict in pyparsing. I'm having problems when I have a list of Dicts. The grammar works if the D

Solution 1:

Ok, so I have never worked with pyparsing before, so excuse me if my solution does not make sense. Here we go:

As far as I understand what you need is three main structures. The most common mistake you made was grouping delimitedLists. They are already grouped, so you have an issue of double grouping. Here are my definitions:

for {a,"b"}:

erlangTaggedTuple = Dict(Group(Suppress('{') + erlangAtom + Suppress(',') + erlangValue + Suppress('}') ))

for [{a,"b"}, {c,"d"}]:

erlangDict = Suppress('[') + delimitedList( erlangTaggedTuple ) + Suppress(']')

for the rest:

erlangList <<= Suppress('[') + delimitedList( Group(erlangDict|erlangList) ) + Suppress(']')

So my fix for your code is:

#!/usr/bin/env python2.7from pyparsing import *

# Erlang config file definition:
erlangAtom = Word( alphas + '_')
erlangString = dblQuotedString.setParseAction( removeQuotes )

erlangValue = Forward()
erlangList = Forward()

erlangTaggedTuple = Dict(Group(Suppress('{') + erlangAtom + Suppress(',') +
                           erlangValue + Suppress('}') ))
erlangDict = Suppress('[') + delimitedList( erlangTaggedTuple ) + Suppress(']') 
erlangList <<= Suppress('[') + delimitedList( Group(erlangDict|erlangList) ) + Suppress(']')

erlangValue <<= ( erlangAtom | erlangString |
                  erlangTaggedTuple |
                  erlangDict| erlangList )

if __name__ == "__main__":
    working = """
[{foo,"bar"}, {baz, "bar2"}]
"""

    broken = """
[
    [{foo,"bar"}, {baz, "bar2"}],
    [{foo,"bob"}, {baz, "fez"}]
]
"""
    w = erlangValue.parseString(working)
    print w.dump()

    b = erlangValue.parseString(broken)
    print"b[0]:", b[0].dump()
    print"b[1]:", b[1].dump()

Which gives the output:

[['foo', 'bar'], ['baz', 'bar2']]
-baz: bar2-foo: barb[0]: [['foo', 'bar'], ['baz', 'bar2']]
-baz: bar2-foo: barb[1]: [['foo', 'bob'], ['baz', 'fez']]
-baz: fez-foo: bob

Hope that helps, cheers!

Solution 2:

I can't understand why it's not working, because your code looks very much like the JSON example, which handles nested lists just fine.

But the problem seems to happen at this line

erlangElements = delimitedList( erlangValue )

where if the erlangValues are lists, they get appended instead of cons'd. You can kludge around this with

erlangElements = delimitedList( Group(erlangValue) )

which adds an extra layer of list around the top-most element, but keeps your sub-lists from merging.

Post a Comment for "Pyparsing: Grammar For List Of Dictionaries (erlang)"