Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding support to operators like x[y] in infixNotation - should I send a PR? #436

Open
franji-pagaya opened this issue Aug 1, 2022 · 3 comments

Comments

@franji-pagaya
Copy link

Hi ,
I wanted to add x[y] operator to the SQL dialect I am parsing using pyparsing.
I have added a small fix to pyparsing infixNotation which allows left-assoc binary operator with opExpr tuple - see example below.
The chage is 5 lines long - is this a usefull addition? should I send a PR?

UNARY, BINARY, TERNARY = 1, 2, 3
expr << pp.infixNotation(
    expr_term,
    [
        (pp.oneOf("- + ~") | NOT, UNARY, pp.opAssoc.RIGHT),
        (ISNULL | NOTNULL | NOT_NULL, UNARY, pp.opAssoc.LEFT),
        ((LBRACKET, RBRACKET), BINARY, pp.opAssoc.LEFT),   ### new operator.
        (pp.oneOf("* / %"), BINARY, pp.opAssoc.LEFT),
        (pp.oneOf("+ -"), BINARY, pp.opAssoc.LEFT),
        (pp.oneOf("<< >> & |"), BINARY, pp.opAssoc.LEFT),
        (pp.oneOf("< <= > >="), BINARY, pp.opAssoc.LEFT),
        (
            pp.oneOf("= == != <> <=>")
            | IS
            | IN
            | LIKE
            | RLIKE
            | NOT_IN
            | NOT_LIKE
            | NOT_RLIKE,
            BINARY,
            pp.opAssoc.LEFT, AthenaLikeOpNode
        ),
        ((BETWEEN | NOT_BETWEEN, AND), TERNARY, pp.opAssoc.LEFT),
        (
            (IN | NOT_IN) + LPAR + pp.delimitedList(expr).setParseAction(ParamsNode) + RPAR,
            UNARY,
            pp.opAssoc.LEFT,
        ),
        (AND, BINARY, pp.opAssoc.LEFT),
        (OR, BINARY, pp.opAssoc.LEFT),
    ],
)
@ptmcg
Copy link
Member

ptmcg commented Nov 5, 2022

Sorry for taking so long to respond.

In the absence of this feature, I've had to push dereferencing of []'s up into the operand itself. In your case, this would have the effect of pushing the []'s "operator" to the very top of the list.

I'm interested in this idea, but not sure it completely works. Is an expr_term always a valid body of []'s? If it is just for numeric indexing into a sequence, you might define a pseudo-operator that only takes an arith expression in the []'s, and then add it as a unary left-assoc operator.

I'll dabble with this and see what I get. Thanks for the interesting idea!

@ptmcg
Copy link
Member

ptmcg commented Nov 5, 2022

How does this look to you, if you didn't have such a feature?


import pyparsing as pp

ident = pp.common.identifier()
number = pp.common.number()
LBRACK, RBRACK = map(pp.Suppress, "[]")

operand = ident | number
multop = pp.Char("*/%")
addop = pp.Char("+-")
signop = pp.Char("+-")

arith_expr = pp.Forward()
array_index = LBRACK + arith_expr + RBRACK

arith_expr <<= pp.infix_notation(
    operand,
    [
        (array_index, 1, pp.opAssoc.LEFT),
        (signop, 1, pp.opAssoc.RIGHT),
        (multop, 2, pp.opAssoc.LEFT),
        (addop, 2, pp.opAssoc.LEFT),
    ]
)

arith_expr.run_tests("""\
    2+2
    x/40
    x[10]/y
    """)

@ptmcg
Copy link
Member

ptmcg commented Mar 25, 2023

I'm thinking about this a bit more, and I think this would be a nice addition. Please submit a PR with your change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants