Inverse of id()?

Paul McGuire ptmcg at austin.rr.com
Mon May 21 09:51:11 EDT 2007


On May 21, 4:55 am, Paul Boddie <p... at boddie.org.uk> wrote:
>
> < some very kind comments re: pyparsing :) >
>
> You'd even be able to incorporate the parse action, too, with some
> extra magic. As pyparsing is a library which seems to encourage clean
> grammar definitions, I think this makes quite a difference, although I
> now expect to be told that there's a class in the library which
> supports this.
>
> Anyway, back to the scheduled programme...
>
> Paul


Paul -

I'm glad pyparsing is working well for you.  I've struggled with the
unwieldiness of setName and setResultsName since version 0.6 or so,
and yours is an interesting solution.  This is definitely a case of
Python's __setAttr__ to the rescue.  And, no there is nothing in
pyparsing that does anything like this, I think most people write
their own workarounds to this issue.

For instance, Seo Sanghyeon (I believe the same one now working on
IronPython) uses the following technique in the EBNF parser/"compiler"
that he contributed to the pyparsing examples directory:

# list of all the grammar variable names
all_names = '''
integer
meta_identifier
terminal_string
...
'''.split()

# parse actions follow
def do_integer(str, loc, toks):
    return int(toks[0])

...

# now attach names and parse actions (and optionally set debugging)
for name in all_names:
    expr = vars()[name]
    action = vars()['do_' + name]
    expr.setName(name)
    expr.setParseAction(action)
    #~ expr.setDebug()

This requires that you maintain the list of all_names, and it self-
imposes a naming standard for parse actions (which I am loath to
impose on others, in general).

Philosophically, though, there is a distinction between an
expression's name and its results name.  I might define an integer and
use it many times within a grammar.  All are named "integer" (as done
with setName), but I may wish to name the returned results with
different names (such as "age", "numberOfChildren", "birthYear",
etc.), and setResultsName performs this function.

I suppose I could add another operator, such as '/', so that something
like:

re = Regex("(\d*)").setParseAction(lambda t:int(t[0]))/"x"

would be equivalent to:

re = Regex("(\d*)").setParseAction(lambda
t:int(t[0])).setResultsName("x")

But this may be bordering on Perlishness, and it certainly is not as
explicit as "setResultsName" (there are also operator precedence
issues - note that I would need parens to use the '/' operator ahead
of '.setParseAction').  Now if the "as" keyword were opened up as a
customizable operator (__as__), *that* would fill the bill nicely, I
should think.

And finally, no, there is no hidden agenda at incorporating some form
of reverse id() lookup into pyparsing - I simply had an interpreter
open with some leftover pyparsing work in it, so it was a good source
of a non-trivial object that I could try to find, given its id.

-- Paul




More information about the Python-list mailing list