Analizza l'espressione con operatori binari e unari, parole riservate e senza parentesi

Aug 24 2020

Sto cercando di analizzare le espressioni costituite dall'operatore binario +, l'operatore unario note gli identificatori che possono essere qualsiasi stringa alfabetica che non lo sianot

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),
]

In esecuzione

expression.parseString('a + (not b)')

dà quello che mi aspetto

[['a', '+', ['not', 'b']]]

Tuttavia, senza le parentesi

expression.parseString('a + not b')

Ottengo solo il primo token:

['a']

Come posso definire la lingua in modo che funzioni come vorrei senza le parentesi?

(Nel caso reale ci sono più operatori e parole riservate: questo è un passo verso l'analisi della lingua S3 Select)

Risposte

5 zvi Aug 31 2020 at 15:00

In S3 NOTè maggiore di AND:

Precedenza degli operatori La tabella seguente mostra la precedenza degli operatori in ordine decrescente.

(dal sito amazon S3 ).

In quella tabella NOTè sopra AND .

Quindi il tuo codice dovrebbe essere:

identifier = Combine(~CaselessKeyword('not') + Word(alphas))
expression = infixNotation(identifier, [
    (CaselessKeyword('not'), 1, opAssoc.RIGHT),
    ('+', 2, opAssoc.LEFT),
])

A proposito: se " NOTè elencato come inferiore al binario +", allora non a + not bè un'espressione valida. +necessita di due operatori: uno è a, ma not bnon è un operando valido.

BTW2 (dai commenti): per favore, non mescolare +quale è un operatore aritmetico e NOTquale è un operatore logico nella stessa espressione. 1 + not 2non è un'espressione valida. Ogni lingua decide come analizzare questo tipo di espressioni strane.