开发者

How to pass values to pyparsing parseactions?

开发者 https://www.devze.com 2023-03-04 03:09 出处:网络
Specifically I want to write a generic parseaction function which will verify 开发者_如何学Pythonranges of numbers. I want to pass a min & max to the function. Is this possible ?Use a closure, som

Specifically I want to write a generic parseaction function which will verify 开发者_如何学Pythonranges of numbers. I want to pass a min & max to the function. Is this possible ?


Use a closure, something like this:

def rangeCheck(minval=None, maxval=None):
    if minval is None and maxval is None:
        # this exception occurs not at parse time, but while defining the grammar
        raise ValueError("minval or maxval must be specified")

    def rangeCheckParseAction(string, loc, tokens):
        parsedval = tokens[0]
        if minval is not None:
            if maxval is not None:
                valid = minval <= parsedval <= maxval
            else:
                valid = minval <= parsedval
        else:
            if maxval is not None:
                valid = parsedval <= maxval

        if not valid:
            raise ParseException(string, loc, 
                    "value not in range (%s,%s)" % (minval, maxval))

    return rangeCheckParseAction

integer = Combine(Optional(oneOf("+ -")) + Word(nums))
integer.setParseAction(lambda t:int(t[0]))

month = integer.copy().addParseAction(rangeCheck(1,12))
day = integer.copy().addParseAction(rangeCheck(1,31))
year = integer.copy().addParseAction(rangeCheck(2000))

SLASH = Suppress('/')
dateExpr = year + SLASH + month + SLASH + day
print dateExpr.parseString("2011/5/8")
print dateExpr.parseString("1999/12/31")

Prints:

[2011, 5, 8]
Traceback (most recent call last):
  File "rangeCheck.py", line 21, in <module>
    print dateExpr.parseString("1999/12/31")
  File "c:\python26\lib\site-packages\pyparsing.py", line 1100, in parseString
    raise exc
pyparsing.ParseException: value not in range (2000,None) (at char 0), (line:1, col:1)

Of course, a better parse action would be to validate the entire date - this current parser would accept '2000/2/31', for instance.

Here's an exercise for the reader: write a parse action to convert the parsed date tokens to a datetime, and then use the exact same rangeCheck parse action to verify that a given time stamp is within a permitted range of datetime values.

(Note that I did not include the string->int conversion in rangeCheck, but broke this up into 2 separate parse actions, so rangeCheck can be used to validate any type that supports < and >. Just be sure to call addParseAction vs. setParseAction, so that pyparsing will continue to do the integer conversion parse action first.)

You can find other examples like this in pyparsing itself - withAttribute is such a method that creates a parse action to verify that an XML or HTML tag has a particular attribute, optionally with a particular value.


Em, do yo mean something like:

def parseaction(num, min = -100, max = 100):
    return min < num < max
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号