web-dev-qa-db-ja.com

操車場アルゴリズム

shunting-yard algorithm が構文の観点から式が正しく記述されていないかどうかを判断できるすべてのケースに興味があります。

したがって、操車場アルゴリズムは、中置記法で記述された式を受け取り、それを接頭辞または後置記法に変換します。簡単な例として、ウィキペディアから抜粋したもの:方程式の中置記法は3 + 4×2÷(1 − 5)^ 2 ^ 3そして、アルゴリズムで後置に変換された後、それは3 42×15 − 2 3 ^ ^÷+になります。

ウィキペディアのアルゴリズムは、2つのケースで括弧の不一致をチェックします。まず、右角かっこが見つかった場合は、左角かっこが見つかるまで演算子をポップします。見つからなかった場合は、かっこが一致しません。次に、すべてのトークンが読み取られた後、オペレータースタックが出力キューにポップされます。角かっこが残っている場合は、括弧が一致していません。これらの2つのことは、アルゴリズムを使用して実行できます。

さて、後置記法での私の表現3 42×15 − 2 3 ^ ^÷+これから、私の中置記法はどれほど正確に言えるでしょうか。正しく書かれていますか?この式が評価された後、スタックに複数の要素がある場合はエラーがあると私は考えていました。私が考慮すべき他のいくつかのケースは何ですか?

1
Shury

演算子の多様性を簡単に調べることができれば、Postfix表記は静的にチェックするのが簡単です。すべての要素を反復処理して、評価スタック上の要素の数を追跡できます。このサイズは常に少なくとも1つでなければなりません。最後に、サイズは正確に1でなければなりません。検証用の擬似コード:

operations = [...]
size = 0

for operand in operations:
  switch operand type:
    case literal:
      size = size + 1
    case operator:
      assert size >= arity(operand)
      size = size + 1 - arity(operand)

assert size == 1

ただし、単純な電卓言語の場合、コードを実行して一貫性のない状態につながるかどうかを確認するよりも、静的分析を実行する利点はありません。

2
amon

中置を解析するときのもう1つの問題は、2つの数値または2つの演算子が隣り合っている場合です。2 2 + + 3

これを確認するには、演算子または左括弧の後に数字または左括弧のみを受け入れ、数字または右括弧の後に演算子または右括弧のみを受け入れます。

if(expectOperator){
    if(token.type == NUMBER || token.type == LEFT_PAREN){
        error("expect operator");
    } 
} else{
    if(token.type == OPERATOR || token.type == RIGHT_PAREN){
        error("expect number");
    } 
}
if(token.type != RIGHT_PAREN && token.type != LEFT_PAREN)
    expectOperator =! expectOperator;
1
ratchet freak