バイナリ演算子と単項演算子、予約語を使用し、括弧を使用せずに式を解析します

Aug 24 2020

二項演算子+、単項演算子not、およびそうでない任意のアルファベット文字列である可能性のある識別子で構成された式を解析しようとしています。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),
]

ランニング

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

私が期待するものを与える

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

ただし、括弧なし

expression.parseString('a + not b')

私は最初のトークンだけを取得します:

['a']

括弧なしで希望どおりに機能する言語を定義するにはどうすればよいですか?

(実際の場合、より多くの演算子と予約語があります。これは、S3 Select言語を解析するためのステップです)

回答

5 zvi Aug 31 2020 at 15:00

S3NOTではそれより高いですAND

演算子の優先順位次の表は、演算子の優先順位を降順で示しています。

(S3アマゾンサイトから)。

その表でNOT上にあり ANDます。

したがって、コードは次のようになります。

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

ところで-「NOTバイナリ+」よりも低い値としてリストされている場合、それa + not bは有効な式ではありません。+2つの演算子が必要です。1つはですがanot b有効なオペランドではありません。

ところで(コメントから):同じ式で+算術演算子とNOT論理演算子を混在させないでください。1 + not 2は有効な式ではありません。すべての言語は、そのような奇妙な表現をどのように解析するかを決定します。