问题
I have defined these as part of my grammar in pyparsing
argument = oneOf(valid_arguments)
function_name = oneOf(valid_functions)
function_call = Group(function_name + LPAR + argument + RPAR)
where valid_argument
and valid_function
are lists of strings containing valid argument names and function names respectively.
Now I want to generate custom exceptions in case if the column name is not part of valid_arguments and function_name is not one of the function names. How can I do that with pyparsing?
Example:
arguments = ["abc", "bcd", "efg"]
function_names = ['avg', 'min', 'max']
if I parse avg(xyz)
, I should want to raise InvalidArgumentError
and if I parse sum(abc)
I want to raise InvalidFunctionError
both of which I have defined in a separate module called exceptions.py
回答1:
You can raise any kind of exception within a parse action, but to get the exception to get reported all the way back to your calling code, have your exception class derive from ParseFatalException. Here is your example with your requested special exception types.
from pyparsing import *
class InvalidArgumentException(ParseFatalException):
def __init__(self, s, loc, msg):
super(InvalidArgumentException, self).__init__(
s, loc, "invalid argument '%s'" % msg)
class InvalidFunctionException(ParseFatalException):
def __init__(self, s, loc, msg):
super(InvalidFunctionException, self).__init__(
s, loc, "invalid function '%s'" % msg)
def error(exceptionClass):
def raise_exception(s,l,t):
raise exceptionClass(s,l,t[0])
return Word(alphas,alphanums).setParseAction(raise_exception)
LPAR,RPAR = map(Suppress, "()")
valid_arguments = ['abc', 'bcd', 'efg']
valid_functions = ['avg', 'min', 'max']
argument = oneOf(valid_arguments) | error(InvalidArgumentException)
function_name = oneOf(valid_functions) | error(InvalidFunctionException)
# add some results names to make it easier to get at the parsed data
function_call = Group(function_name('fname') + LPAR + argument('arg') + RPAR)
tests = """\
avg(abc)
sum(abc)
avg(xyz)
""".splitlines()
for test in tests:
if not test.strip(): continue
try:
print test.strip()
result = function_call.parseString(test)
except ParseBaseException as pe:
print pe
else:
print result[0].dump()
print
prints:
avg(abc)
['avg', 'abc']
- arg: abc
- fname: avg
sum(abc)
invalid function 'sum' (at char 4), (line:1, col:5)
avg(xyz)
invalid argument 'xyz' (at char 8), (line:1, col:9)
来源:https://stackoverflow.com/questions/13393432/raise-a-custom-exception-in-pyparsing