Search code examples
pythonpyparsing

Pyparsing validation on AND/OR keyword without further expression


I have a formula format that supports AND and OR:

import pyparsing as pp

# Basic literals.
DOUBLE_QUOTE = pp.Literal('"')
SINGLE_QUOTE = pp.Literal("'")
AND_OR = pp.oneOf("AND OR", True)
CONDITION = pp.oneOf("> < = >= <=")

# Left and right hand sides.
lhs = pp.Word(pp.alphas + pp.alphas8bit + pp.alphanums + "." + "_")
rhs_str = pp.Word(pp.alphas + pp.alphas8bit + pp.alphanums + "." + "_" + "-" + ":")
rhs_num = pp.Word(pp.nums)
rhs = (
    (DOUBLE_QUOTE + rhs_str + DOUBLE_QUOTE)
    | (SINGLE_QUOTE + rhs_str + SINGLE_QUOTE)
    | (rhs_num)
)

# Basic expressions.
# Samples:
# * user.id = 10
# * name = "user" and user.id > 10
one_expr = lhs + CONDITION + rhs
unpack_expr = one_expr + pp.ZeroOrMore(AND_OR + one_expr)

For example:

>>> print(unpack_expr.parseString("a = 10 and b = 2"))
['a', '=', '10', 'AND', 'b', '=', '2']

It works fine but when I add another AND/OR keyword at the end of the expression but without any further expression, it still works fine while I expected to get an error:

>>> print(unpack_expr.parseString("a = 10 and b = 2 or"))
['a', '=', '10', 'AND', 'b', '=', '2']

Solution

  • To solve the issue, you need to use stringEnd():

    import pyparsing as pp# Basic literals.
    DOUBLE_QUOTE = pp.Literal('"')
    SINGLE_QUOTE = pp.Literal("'")
    AND_OR = pp.oneOf("AND OR", True)
    CONDITION = pp.oneOf("> < = >= <=")# Left and right hand sides.
    lhs = pp.Word(pp.alphas + pp.alphas8bit + pp.alphanums + "." + "_")
    rhs_str = pp.Word(pp.alphas + pp.alphas8bit + pp.alphanums + "." + "_" + "-" + ":")
    rhs_num = pp.Word(pp.nums)
    rhs = (
        (DOUBLE_QUOTE + rhs_str + DOUBLE_QUOTE)
        | (SINGLE_QUOTE + rhs_str + SINGLE_QUOTE)
        | (rhs_num)
    )# Basic expressions.
    # Samples:
    # * user.id = 10
    # * name = "user" and user.id > 10
    one_expr = lhs + CONDITION + rhs
    unpack_expr = one_expr + pp.ZeroOrMore(AND_OR + one_expr) + pp.stringEnd()