[Python] Using pyparsing to parse infix expression

Discussão em 'Python' iniciado por Stack, Setembro 26, 2024.

  1. Stack

    Stack Membro Participativo

    I am learning Paul McGuire's fabulous pyparsing Python module. I'm posting this for discussion and hopefully to get a deeper insight into pyparsing.

    The following code parses a parenthetical expression that looks similar to a Django Q() object expression used for querying data. Here is an example expression:

    '( title__regex=r"^(An?|The) +" ) | ( id__in=[1, 3, 4] )'


    Here's the code:

    import pyparsing as p

    ident = p.Word(p.identchars, p.identbodychars)
    cond_op = p.Opt('!') + '='
    quoted_string = p.quoted_string
    unquoted_string = p.Word(p.string.printable, exclude_chars='()\'"')
    rvalue = p.OneOrMore(quoted_string | unquoted_string)
    infix_operator = p.one_of('& | ^').set_name('"logical operator"')
    whitespace = p.ZeroOrMore(p.White())
    expr = p.infix_notation(
    p.Combine(ident + whitespace + cond_op + whitespace + rvalue),
    [(infix_operator, 2, p.opAssoc.LEFT)]
    )

    string = '( title__regex=r"^(An?|The) +" ) | ( id__in=[1, 3, 4] )'

    try:
    results = expr.parse_string(string, parse_all=True).as_list()
    except p.ParseException as e:
    print(e.explain())
    else:
    print(results)


    The code correctly outputs:

    [['title__regex=r"^(An?|The) +"', '|', 'id__in=[1, 3, 4]']]


    What other solutions are there?

    Is there a better way to express a sequence of unquoted and quoted characters? Here quotes prevent parens from being interpreted as the end or start of a parenthetical expression.

    If I mangle the input string by removing the = char, i.e. title__regex r"^(An?|The) +", the parser returns:

    (title__regex r"^(An?|The) +") | (id__in=[1, 3, 4])
    ^
    ParseException: Expected "logical operator" term, found 'r' (at char 14), (line:1, col:15)


    Why is the parser expecting a "logical operator"? It should be expecting "=".

    Continue reading...

Compartilhe esta Página