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

Original source