Parser or regex ?

Paul McGuire ptmcg at austin.rr._bogus_.com
Sat Dec 17 08:26:11 CET 2005


"Fuzzyman" <fuzzyman at gmail.com> wrote in message
news:1134747830.853903.297030 at o13g2000cwo.googlegroups.com...
>
> Tim Arnold wrote:
> > "Fuzzyman" <fuzzyman at gmail.com> wrote in message
> > news:1134743933.931635.77490 at f14g2000cwb.googlegroups.com...
> > > Hello all,
> > >
> > > I'm writing a module that takes user input as strings and
(effectively)
> > > translates them to function calls with arguments and keyword
> > > arguments.to pass a list I use a sort of 'list constructor' - so the
> > > syntax looks a bit like :
> > >
> > >   checkname(arg1, "arg 2", 'arg 3', keywarg="value",
> > > keywarg2='value2', default=list("val1", 'val2'))
> > >
> > > Worst case anyway :-)
> > >
> >
> > pyparsing is great, easy to configure and very powerful--I think it
looks
> > like a great tool for your inputs.
> >
>
> Thanks - I considered it. It's actually quite a small module (about
> 38k). I don't want to introduce a dependency on an external module.
>
> All the best,
>
> Fuzzyman
> http://www.voidspace.org.uk/python/index.shtml
>
> > http://pyparsing.sourceforge.net/
> >
> >
> > --Tim
>

Fuzzy -

This wont make the pyparsing module any smaller or less external, but here's
a pyparsing grammar for you.
- handles parameter values of single or double quoted strings, numbers, or
lists
- handles nested list values
- defines the grammar in just 8 readable lines

The simple version shows the basic pyparsing code, the fancy version adds
results names, which make the results processing step simpler.

-- Paul


data = """checkname(arg1, "arg 2", 'arg 3', keywarg="value",
    keywarg2='value2', default=list("val1", 'val2',list("val3.1",
'val3.2')))"""

# simple version
from pyparsing import *

ident = Word(alphas,alphanums+"_$")
fname = ident
number = Word(nums,nums+".")
listDef = Forward()
val = quotedString | number | listDef
listDef << Group( Literal("list") + "(" + delimitedList(val) + ")" )
param = Group((ident | quotedString) + Optional(Literal("=").suppress() +
val) )
fn = fname.setResultsName("func") + "(" +
Group(Optional(delimitedList(param))) + ")"

res = fn.parseString(data)
import pprint
pprint.pprint(res.asList())

prints:
['checkname',
 '(',
 [['arg1'],
  ['"arg 2"'],
  ["'arg 3'"],
  ['keywarg', '"value"'],
  ['keywarg2', "'value2'"],
  ['default',
   ['list',
    '(',
    '"val1"',
    "'val2'",
    ['list', '(', '"val3.1"', "'val3.2'", ')'],
    ')']]],
 ')']

# fancy version, using results names
ident = Word(alphas,alphanums+"_$")
fname = ident
number = Word(nums,nums+".")
listDef = Forward()
val = quotedString | number | listDef
listDef << Group( Literal("list") + Suppress("(") + delimitedList(val) +
Suppress(")") )
noParam = object()
param = Group((ident | quotedString).setResultsName("name") + \
        Optional(Literal("=").suppress() + val,
default=noParam).setResultsName("val") )
fn = fname.setResultsName("func") + "(" + \
        Group(Optional(delimitedList(param))).setResultsName("params") + ")"

res = fn.parseString(data)

print "func:", res.func
print "params:"
for p in res.params:
    if p.val != noParam:
        print "-",p.name,"=",p.val
    else:
        print "-",p.name

prints:

func: checkname
params:
- arg1
- "arg 2"
- 'arg 3'
- keywarg = "value"
- keywarg2 = 'value2'
- default = ['list', '"val1"', "'val2'", ['list', '"val3.1"', "'val3.2'"]]







More information about the Python-list mailing list