Hey, Thanks Neil and Paul!
After reading Neil's advice I started playing around with the setParseAction method, and then I found Paul's script 'macroExpander.py' (http://pyparsing.wikispaces.com/space/showimage/ macroExpander.py). With only a few modifications to macroExpander.py (and reversing my string!) I had an almost complete answer of: first [second1_1 second1_2 | second2 | second3 ] [third1 third2 | [sixth1_1 sixth1_2 | sixth2 ] ] | fourth [fifth1 | [[eighth1 | eighth2] | seventh1]] I was in the process of tyding this up so that I could do an eval() to get the array when I saw Paul's answer (thanks!) Here is macroExpander.py with my minimal changes: #!/usr/bin/python from pyparsing import * # define the structure of a macro definition (the empty term is used # to advance to the next non-whitespace character) label = Suppress(":") + Word(alphas + "_").setResultsName("macro") + Suppress(":") values = restOfLine.setResultsName("value") macroDef = label + empty + values # define a placeholder for defined macros - initially nothing macroExpr = Forward() # global dictionary for macro definitions macros = {} # parse action for macro definitions def processMacroDefn(s,l,t): macroVal = macroExpander.transformString(t.value) macros[t.macro] = macroVal macroExpr << MatchFirst( map(Keyword,macros.keys()) ) # parse action to replace macro references with their respective definition def processMacroRef(s,l,t): return '[' + macros[t[0]] +']' # attach parse actions to expressions macroExpr.setParseAction(processMacroRef) macroDef.setParseAction(processMacroDefn) # define pattern for scanning through the input string macroExpander = macroExpr | macroDef # test macro substitution using transformString testString = """ :EIGHTH: eighth1 | eighth2 :SEVENTH: EIGHTH | seventh1 :SIXTH: sixth1_1 sixth1_2 | sixth2 :FIFTH: fifth1 | SEVENTH :THIRD: third1 third2 | SIXTH :SECOND: second1_1 second1_2 | second2 | second3 :Start: first SECOND THIRD | fourth FIFTH """ macroExpander.transformString(testString) print macros['Start'] -- http://mail.python.org/mailman/listinfo/python-list