converting a string to a function parameter
andrew cooke
andrew at acooke.org
Sat Mar 28 07:37:51 EDT 2009
I'm a bit late to the party, but LEPL 2.2, just released, can now handle
this too. I suspect email may mangle this, so you can also read it at
http://www.acooke.org/lepl/examples.html#parsing-a-python-argument-list
from lepl import *
comma = Drop(',')
none = Literal('None') >> (lambda x: None)
bool = (Literal('True') | Literal('False')) >> (lambda x: x == 'True')
ident = Word(Letter() | '_',
Letter() | '_' | Digit())
float_ = Float() >> float
int_ = Integer() >> int
str_ = String() | String("'")
item = str_ | int_ | float_ | none | bool | ident
with Separator(~Regexp(r'\s*')):
value = Delayed()
list_ = Drop('[') & value[:, comma] & Drop(']') > list
tuple_ = Drop('(') & value[:, comma] & Drop(')') > tuple
value += list_ | tuple_ | item
arg = value >> 'arg'
karg = (ident & Drop('=') & value > tuple) >> 'karg'
expr = (karg | arg)[:, comma] & Drop(Eos()) > Node
parser = expr.string_parser()
ast = parser('True, type=rect, sizes=[3, 4], coords = ([1,2],[3,4])')
print(ast[0])
which gives:
Node
+- arg True
+- karg (u'type', u'rect')
+- karg (u'sizes', [3, 4])
`- karg (u'coords', ([1, 2], [3, 4]))
you can then access those values:
>>> ast[0].arg
[True]
>>> ast[0].karg
[('type', 'rect'), ('sizes', [3, 4]), ('coords', ([1, 2], [3, 4]))]
alternatively, you could avoid using a Node altogether and just put them
in a list or whatever....
andrew
Paul McGuire wrote:
> from pyparsing import *
>
> LPAR,RPAR,LBRACK,RBRACK,EQ,COMMA = map(Suppress,"()[]=,")
>
> noneLiteral = Literal("None")
> boolLiteral = oneOf("True False")
> integer = Combine(Optional(oneOf("+ -")) + Word(nums)).setName
> ("integer")
> real = Combine(Optional(oneOf("+ -")) + Word(nums) + "." +
> Optional(Word(nums))).setName("real")
>
> ident = Word(alphas+"_",alphanums+"_")
>
> listStr = Forward().setName("list")
> tupleStr = Forward().setName("tuple")
> listItem = real | integer | noneLiteral | boolLiteral | \
> quotedString.setParseAction(removeQuotes) | Group(listStr) |
> tupleStr | ident
> listStr << ( LBRACK + Optional(delimitedList(listItem)) + Optional
> (COMMA) + RBRACK )
> tupleStr << (LPAR + Optional(delimitedList(listItem)) + Optional
> (COMMA) + RPAR)
>
> # parse actions perform parse-time conversions
> noneLiteral.setParseAction(lambda: None)
> boolLiteral.setParseAction(lambda toks: toks[0]=="True")
> integer .setParseAction(lambda toks: int(toks[0]))
> real .setParseAction(lambda toks: float(toks[0]))
> listStr .setParseAction(lambda toks: toks.asList())
> tupleStr .setParseAction(lambda toks: tuple(toks.asList()))
>
> arg = Group(ident("varname") + EQ + listItem("varvalue")) | listItem
>
>
> argstring = 'True, type=rect, sizes=[3, 4,], coords = ([1,2],[3,4])'
>
> parsedArgs = delimitedList(arg).parseString(argstring)
> args = []
> kwargs = {}
> for a in parsedArgs:
> if isinstance(a,ParseResults):
> if isinstance(a.varvalue,ParseResults):
> val = a.varvalue.asList()
> else:
> val = a.varvalue
> kwargs[a.varname] = val
> else:
> args.append(a)
>
> print "Args:", args
> print "Kwargs:", kwargs
>
>
> Prints:
>
> Args: [True]
> Kwargs: {'coords': ([1, 2], [3, 4]), 'type': 'rect', 'sizes': [3, 4]}
>
> --
> http://mail.python.org/mailman/listinfo/python-list
>
>
More information about the Python-list
mailing list