Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parse expression with binary and unary operators, reserved words, and without parentheses

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)

like image 571
Michal Charemza Avatar asked Aug 23 '20 20:08

Michal Charemza


People also ask

What is the difference between unary and binary operators give example?

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.

What is the difference between unary and binary and ternary operator?

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.

What is unary operator in JavaScript?

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.

Does Python have unary operators?

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.


1 Answers

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.

like image 118
zvi Avatar answered Oct 10 '22 09:10

zvi