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)
There are two types of mathematical operators: unary and binary. Unary operators perform an action with a single operand. Binary operators perform actions with two operands. In a complex expression, (two or more operands) the order of evaluation depends on precedence rules.
Unary operators perform an action upon a single operand, binary operators perform an action upon two operands, and ternary operators perform an action involving three operands.
A unary operation is an operation with only one operand. This operand comes either before or after the operator. Unary operators are more efficient than standard JavaScript function calls. Additionally, unary operators can not be overridden, therefore their functionality is guaranteed.
The – operator in Python can be utilized in a unary form. The unary structure implies character, restoring the same value as its operand. The unary structure implies negate, restoring the nullified incentive as its operand: zero to zero, positive to negative, and negative to positive.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With