On Jul 26, 10:40 pm, [EMAIL PROTECTED] wrote: > 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). > <snip>
Great! I'm glad those examples are useful (I keep meaning to get them a little better organized.) Just one side note. macroExpander uses the Forward class in a non- traditional way. The Forward class is usually used to define a recursive grammar, like in this simple list grammar that defines a comma-separated list, with nested sublists enclosed in parentheses: listExpr = Forward() listItem = Word(alphanums) | Group( '(' + listExpr + ')' ) listExpr << delimitedList( listItem ) I need to use listExpr as part of the definition of listItem, but I need to use listItem to define listExpr. So I "forward declare" listExpr by calling it a Forward instance, then I "inject" the grammar contents using the shift '<<' operator when I have defined listItem. macroExpander is a little different. In this case, I'm using a Forward as a parse-time dynamic grammar element. A Forward is used as a placeholder for all previously seen macro names, beginning as an empty Forward (an empty Forward never matches). As new macro definitions are found, the placeholder content gets defined as a MatchFirst of all macro definitions that have been seen so far - sort of a self-modifying parser. This explains why you had to reverse the order of your example string when you adapted macroExpander to your example. Your original string referenced macros that hadn't been encountered yet, so the only way to handle that was to parse everything, and then recursively post-process the structure with a parse action on the top-level expression. (I tried a version using parse actions on the all-uppercase macro expression, and a dict of previously-seen references and placeholders in the cumulative ParseResults, but I couldn't get this working, so I went with the recursive post-process instead - much simpler and more straightforward.) Glad you worked out your question, hope to hear from you further in your pyparsing exploits. -- Paul -- http://mail.python.org/mailman/listinfo/python-list