I'm trying to parse expressions made of the binary operator +
, the unary operator not
and identifiers that can be any alphabetical string that isn't not
from pyparsing import (
CaselessKeyword,
Combine,
Word,
alphas,
opAssoc,
infixNotation,
)
identifier = Combine(~CaselessKeyword('not') + Word(alphas))
expression = infixNotation(identifier, [
('+', 2, opAssoc.LEFT),
(CaselessKeyword('not'), 1, opAssoc.RIGHT),
]
Running
expression.parseString('a + (not b)')
gives what I expect
[['a', '+', ['not', 'b']]]
However, without the parentheses
expression.parseString('a + not b')
I only get the first token:
['a']
How can I define the language to work as I would like without the parentheses?
(In the real case there are more operators and reserved words: this is a step towards parsing the S3 Select language)
In S3 NOT
is higher that AND
:
Operator Precedence The following table shows the operators' precedence in decreasing order.
(from S3 amazon site).
In that table NOT
is above AND
.
So your code should be:
identifier = Combine(~CaselessKeyword('not') + Word(alphas))
expression = infixNotation(identifier, [
(CaselessKeyword('not'), 1, opAssoc.RIGHT),
('+', 2, opAssoc.LEFT),
])
BTW - If "NOT
is listed as a lower than the binary +
", than a + not b
is not valid expression. +
needs two operators: one is a
, but not b
is not valid operand.
BTW2 (from comments):
Please don't mix +
which is an arithmetic operator and NOT
which is a logic operator in the same expression. 1 + not 2
is not a valid expression.
Every language decide how to parse that's kinds of strange expressions.