Raise a custom exception in pyparsing
pyparsing, python
Solution
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)
Problem
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