web-dev-qa-db-ja.com

左右のほとんどの派生

だから、私はバッカスナウルフォームが行く限り、派生のセマンティクスを理解しています。オンラインの教科書や講師のメモには見当たらないことが一つあります。

最も右側の派生が最も左側の派生よりも有益なのはいつですか?コンパイラーまたはジェネレーターは常に左か右のどちらを使用しますか、それとも両方を使用しますか?

だからここに例があります:

次の言語の文があるとします:A = B + C * A

上記を許可する言語文法の例:

<assign>  <id> = <expr> 
<id>  A | B | C
<expr>  <expr> + <term>
        |<term>
<term> <term> * <factor> 
       |<factor>
<factor>  ( expr )
        | <id>

最も左側の派生:

<assign>   => <id> = <expr>
              => A = <expr> + <term>
              => A = <term> + <term>  
              => A = <factor> + <term> 
              => A = <id> + <term> 
              => A = B + <term> 
              => A = B + <term> * <factor>
              => A = B + <factor> * <factor>
              => A = B + <id> * <factor>
              => A = B + C * < term>
              => A = B + C * <factor>
              => A = B + C * <id>
              => A = B + C * A

最も適切な派生:

<assign>  => <id> = <expr>
      => <id> = <expr> + <term>
      => <id> = <expr> + <term>   * <factor>
      => <id> = <expr> + <term> * <id>
      => <id> = <expr> + <term> * A
      => <id> = <expr> + <factor> * A
      => <id> = <expr> + <id> * A
      => <id> = <expr> + C * A
      => <id> = <term> + C * A
      => <id> = <id> + C * A
      => <id> = B + C * A
      =>  A = B + C * C  
6
Andrew S

それが30年以上前に私のコンパイラクラスで説明された方法は、左端の派生スキームがトップダウン(たとえば、再帰的降下)パーサーで最適に機能し、右端の派生スキームがボトムアップ(たとえば、SLR(1)、LALR(1)、YACCなど)パーサー。ボトムアップパーサーで左端の派生スキームを使用するには、短いフレーズを一度に認識するのではなく、パーサーがセンテンス全体を「積み上げ」てから右端から処理する必要があります。反対のペアリングも同じです。

私の グリーンドラゴンブックレッドドラゴンブック は現在保管されています。


それについて少し考えた後、上記の議論は左再帰と右再帰の文法についてですが、効果は同じだと思います。当時、文法を実行するための「最良の」方法は1つではないと言っていたので、結果は非常に満足できるものであることがわかりました。

6
John R. Strohm

それ自体では、左端と右端の両方の派生は、CFGで解析または生成するときに実行する手順を明確にする任意のルールにすぎません。最終的に同じツリー、およびLMDにつながる非終端展開のさまざまな順序が考えられますとRMDは、どちらのルートを取るかを決定するための単純な2つの単純な戦略です。

コンピュータの場合、自分で決定を下すことができないため、このような任意のルールを持つことが不可欠です。彼らができることは、いくつかの厳密なルールに従うか、すべての可能性を試し、必要に応じてバックトラックすることです。バックトラッキングは、可能性のある空間の検索に相当します。単純なルールでもうまくいく場合は、無駄になります。事実上すべてのプログラミング言語が定義されているため、確定的なパーサーのみが必要であり、多くの場合、先読み範囲が非常に限定された確定的なパーサーのみが必要です。

2
Kilian Foth

トップダウンまたは再帰的降下パーサー(LL(k))は、左側の派生を構築します。最初の図は、そのような解析のステップの概要を示しています。

ボトムアップ(SLR(k)またはLALR(k))パーサーは、正しい派生を構築します。 2番目の図は、このような解析の手順の概要を示しています。

この議論に欠けているのは、適切な文法の違いです。文法が次のようになっている場合:

<expr> := <term>
        | <term> + <expr>

左側の派生はバックトラックすることが示され、LL(k)パーサーにはあまり適していません。正しい導出はそうではなく、それでもボトムアップ解析に適しています。他の文法では、正しい導出が問題を引き起こします。

これらのメソッドの主な理由は、私が過去に使用したように、リファクタリングによって対処できる文法の問題を示し、特定の種類のパーサーにより適したものにするためです。

2
david.pfx

左端の派生は簡単に構築でき、トップダウン解析で使用できます。トップダウンパーサーは実装が簡単ですが、一部の文法セットしか処理できません。つまり、処理できません。

  1. あいまいな文法
  2. 左再帰文法
  3. 非決定論的文法(左因数分解)

そのため、ほとんどの派生は、すべてのクラスの文法を解析するために使用されるわけではありません。

ボトムアップパーサーは上記のすべての文法を処理でき、BUPはRMDを逆に使用します。 RMDは、すべてのクラスの文法を解析するために使用されます。

最後に、RMDはLMDよりも強力で効率的です。

1
prasada rao