素人の言葉で言えば、左再帰とは何ですか?


11

code.google.comの1ページによると、「左再帰」は次のように定義されています。

左再帰とは、再帰的な非終端記号を指し、それ自体を含む知覚形式を生成する場合、それ自体の新しいコピーが生成規則の左側に表示されます。

ウィキペディアには、2つの異なる定義があります。

  1. 文脈自由文法の観点では、rの生成(「代替」)の左端の記号がすぐ(直接/即時左再帰)または他の非終端記号を介して、非終端記号rが左再帰である場合定義(間接/非表示の左再帰)は、rに再度書き換えます。

  2. 「文法が左再帰的であるのは、それ自体が左記号として最終的に文型を導き出す非終端記号Aを見つけることができる場合です。」

私はここで言語作成を始めたばかりで、暇なときにそれをやっています。ただし、言語パーサーの選択に移ると、このパーサーで左再帰がサポートされているか、そのパーサーがすぐに前面および中央に表示されるかが問題になります。「文型」などの用語を検索しても、専門用語のリストが表示されるだけですが、「左」再帰の区別はほとんど非常に単純でなければなりません。翻訳をお願いします?

回答:


19

ルールRR一致するかどうかを調べるために、最初に一致するかどうかを調べる必要がある場合、ルールは左再帰的ですR。これはR、直接または間接的に、それ自体の生産の最初の用語として現れるときに起こります。

気を散らすのを避けるために、加算と乗算のみを使用して、数学式のおもちゃの文法を想像してください。

Expression ::= Multiplication '+' Expression
            || Multiplication

Multiplication ::= Term '*' Term
                 || Term

Term ::= Number | Variable

書かれているように、ここには左再帰はありません。この文法を再帰下降パーサーに渡すことができます。

しかし、次のように記述しようとしたと仮定します。

Expression ::= Expression '*' Expression
            || Expression '+' Expression
            || Term

Term ::= Number | Variable

これは文法であり、一部のパーサーはそれに対処できますが、再帰降下パーサーとLLパーサーはできません—のルールはそれ自体でExpression始まるためExpressionです。再帰下降パーサーで、実際に入力をまったく消費せずに無制限の再帰が発生する理由は明らかです。

ルールがそれ自体を直接または間接的に参照するかどうかは関係ありません。場合Aの代替を持っていると開始していることB、およびB代替開始とのことを持っているがA、その後、AおよびB両方の間接左再帰され、それらのマッチング機能パーサ再帰下降に無限の相互再帰をもたらすことになります。


だから、第二の例では、あなたは後に非常に最初のものを変更しない場合::=からExpressionTerm、そしてあなたが最初の後に同じことをやっている場合||、それはもはや左再帰的なことでしょうか?しかし、で::=なく||、でした後で、それがまだ左再帰だとしたらどうでしょうか?
パンツァークライシス14

多くのパーサーが左から右に移動し、すべてのシンボルで停止し、その場で再帰的に評価すると言っているようです。この場合、最初のExpressionがで切り替えられた場合、最初ののTerm::=と後の両方||で問題はありません。遅かれ早かれ、それはどちらのあるものに実行されますので、NumberVariable、それによってその何かのではないかを決定することができるという、Expression...さらに実行せず
Panzercrisis

...しかし、それらのいずれかがまだで始まっているExpression場合、潜在的にa Termではないものが見つかる可能性があり、すべてが何度も繰り返されるかどうかをチェックし続けるだけExpressionです。これでしょうか?
パンツァークライシス14

1
@Panzercrisisは多かれ少なかれ。LL、LR、および再帰下降パーサーの意味を調べる必要があります。
ホッブズ14

これは技術的には正確ですが、おそらく単純ではありません(素人の用語)。また、実際には、LLパーサーは通常、再帰を検出して回避する機能(プロセスで有効な不自然な文字列を拒否する可能性がある)を追加します。また、実際には、ほとんどのプログラミング言語では、無限再帰を回避する方法。

4

私はそれを素人の言葉に入れて突き刺します。

解析ツリー(ASTではなく、パーサーの訪問と入力の拡張)の観点から考えると、左再帰は左下に成長するツリーになります。右再帰はまったく逆です。

例として、コンパイラの一般的な文法は項目のリストです。文字列のリスト(「赤」、「緑」、「青」)を取得して解析します。いくつかの方法で文法を書くことができました。次の例は、それぞれ直接左または右再帰です。

arg_list:                           arg_list:
      STRING                              STRING
    | arg_list ',' STRING               | STRING ',' arg_list 

これらの解析のツリー:

         (arg_list)                       (arg_list)
          /      \                         /      \
      (arg_list)  BLUE                  RED     (arg_list)
       /       \                                 /      \
   (arg_list) GREEN                          GREEN    (arg_list)
    /                                                  /
 RED                                                BLUE

再帰の方向にどのように成長するかに注意してください。

これは本当に問題ではありません。パーサーツールで処理できる場合は、左の再帰的な文法を記述しても構いません。ボトムアップパーサーはそれをうまく処理します。より現代的なLLパーサーも同様です。再帰文法の問題は再帰ではなく、パーサーを進めない再帰、またはトークンを消費せずに再帰することです。再帰するときに常に少なくとも1つのトークンを消費すると、最終的に解析の最後に到達します。左再帰は、消費なしの再帰として定義されます。これは無限ループです。

この制限は、純粋なトップダウンLLパーサー(再帰下降パーサー)を使用した文法の実装の詳細です。左の再帰文法に固執したい場合は、プロダクションを書き換えて再帰する前に少なくとも1つのトークンを消費することで対処できます。これにより、非生産的なループでスタックすることはありません。左再帰の文法ルールの場合、文法を1レベル先読みにフラット化する中間ルールを追加して、再帰プロダクション間でトークンを消費することで書き換えることができます。(注:これは、一般化された規則を指摘するだけで、これが文法を書き換える唯一の方法または推奨される方法であるとは言いません。この単純な例では、最良のオプションは右再帰形式を使用することです)このアプローチは一般化されているため、パーサージェネレーターは、プログラマーが関与することなく(理論的に)実装できます。実際には、ANTLR 4がまさにそれを行うと信じています。

上記の文法では、左再帰を表示するLL実装は次のようになります。パーサーはリストの予測から始めます...

bool match_list()
{
    if(lookahead-predicts-something-besides-comma) {
       match_STRING();
    } else if(lookahead-is-comma) {
       match_list();   // left-recursion, infinite loop/stack overflow
       match(',');
       match_STRING();
    } else {
       throw new ParseException();
    }
}

現実には、私たちが本当に扱っているのは「単純な実装」です。最初に特定の文を予測し、その予測の関数を再帰的に呼び出し、その関数は同じ予測を単純に呼び出します。

ボトムアップパーサーには、どちらの方向にも再帰的なルールの問題はありません。なぜなら、文の先頭を再解析せず、文を元に戻すことで機能するからです。

文法の再帰は、トップダウンで生成する場合にのみ問題になります。パーサーは、トークンを消費するときに予測を「拡張」することで機能します。LALR(Yacc / Bison)ボトムアップパーサーのように、展開する代わりに折りたたむ(生産が「縮小」される)場合、どちらの側の再帰も問題ではありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.