pyparser and recursion problem

pyscottishguy at pyscottishguy at
Fri Jul 27 18:48:23 CEST 2007


Thanks for the further explanations. I'm going to play around more
with the 'recursive grammar' and 'parse-time dynamic grammar element'
stuff so that I understand it a bit better.

I liked the changes you suggested.  The alternative grammar definitely
makes the code easier to understand, plus the 'delimitedList' function
is very handy.  I can see the usefulness of 'Combine' but it's not
needed here.

This didn't work though:

print res["Start"][0].asList()

But that's ok, because I was more than happy to do:

myArray = [res["Start"]][0]

and have the whole thing as a list.  Very nice indeed :)

Thanks again for your help!

For anyone thats interested, here is the updated code (my original
code with Paul's enhancements)


from pyparsing import Word, OneOrMore, Group,  alphas, \
    alphanums, Suppress, Dict, delimitedList, ParseResults

import string

def allIn( as, members ):
    "Tests that all elements of as are in members"""
    for a in as:
        if a not in members:
            return False
    return True

def allUpper( as ):
    """Tests that all strings in as are uppercase"""
    return allIn( as, string.uppercase )

# recursive reference fixer-upper
def fixupRefsRecursive(tokens, lookup):
    if isinstance(tokens, ParseResults):
        subs = [ fixupRefsRecursive(t, lookup) for t in tokens ]
        tokens = ParseResults( subs )
        if tokens.isupper():
            tokens = fixupRefsRecursive(lookup[tokens], lookup)
    return tokens

def fixupRefs(tokens):
    tokens["Start"] = fixupRefsRecursive( tokens["Start"], tokens )

testData = """
:Start: first SECOND THIRD  fourth FIFTH

:SECOND: second1_1 second1_2 | second2 | second3

:THIRD: third1 third2 | SIXTH

:FIFTH: fifth1 | SEVENTH

:SIXTH: sixth1_1 sixth1_2 | sixth2

:SEVENTH: EIGHTH | seventh1

:EIGHTH: eighth1 | eighth2


COLON = Suppress(":")
label =  COLON + Word(alphas + "_") + COLON
entry = Word(alphanums + "_")
data = delimitedList( Group(OneOrMore(entry)), delim="|" )
line = Group(label + data)
doc = Dict(OneOrMore(line))

doc.setParseAction( fixupRefs )

res = doc.parseString(testData)

myArray = [res["Start"]][0]

print myArray

More information about the Python-list mailing list