左再帰

From Wikipedia, the free encyclopedia

左再帰: Left recursion)とは、言語(普通、形式言語について言うが、自然言語に対しても考えられ得る)の文法(構文規則)にあらわれる再帰的な規則(定義)の特殊な場合で、ある非終端記号を展開した結果、その先頭(最も左)にその非終端記号自身があらわれるような再帰のことである。

ナイーブに再帰下降構文解析の関数に変換すると、実行(ないし評価)すると無限再帰に陥る関数になるのだが、通常の算術の式のように左結合(結合法則#結合性を参照)の中置演算子式は一般に左再帰の構文規則になるため、プログラミング言語処理系の実装のために、実用的な観点から対策が検討されてきた。この関数における再帰を指すこともある。

直接左再帰

文法が左再帰であるとは、非終端記号からその非終端記号自身を左端に含む文字列が導出される、ということである[1]

以下、ラテンアルファベットの大文字(, ,...)は任意の非終端記号を、ギリシャアルファベットの小文字(, ,...)は任意の記号をあらわすものとする。

直接左再帰は、次のような形をした構文規則で発生する。

ここで、 は任意の非終端記号終端記号の並びであり、 の先頭は A ではない。

例えば、次のような規則があるとする。

これは直接左再帰である。これをそのまま再帰下降構文解析で実装したものは次のようになる。

function Expr() {
    Expr();  match('+');  Term();
}

これを実行すると、無限再帰に陥ってしまう。

間接左再帰

間接左再帰の単純な例は、次のようなものになる。


この場合、 のような導出となる可能性がある。

より一般化すると、非終端記号群 についての間接左再帰は次のように定義できる。




ここで、 は非終端記号と終端記号の並びである。

トップダウン構文解析での左再帰対応

左再帰を含む形式文法は、以上のように単純にトップダウンの再帰下降構文解析構文解析しようとすると無限再帰(無限ループ)に陥るため、なんらかの回避策が必要である。一方、LALR法などのボトムアップ構文解析では対照的に、右再帰よりも左再帰の方がスタックが深くならないので、むしろ効率が良いと言える。以下に示すような近年の研究では、トップダウン構文解析でも左再帰型の文法を扱える手法がいくつか示されている。2006年、Frost と Hafiz は、左再帰を含む曖昧な文法を扱う認識アルゴリズムを示した[2]。2007年、Frost、Hafiz、Callaghan はこのアルゴリズムを拡張し、間接左再帰も直接左再帰も多項式時間で扱える構文解析アルゴリズムとし、非常に曖昧な文法であっても指数関数的な数になる構文木を多項式サイズでコンパクトに表現できることを示した[3]。その後、このアルゴリズムは Haskell で書かれた構文解析器生成器で実装された。その実装の詳細は上記研究者らが PADL'08 で発表した論文で示されている[4]X-SAIGAには、このアルゴリズムや実装についてのより詳しい記述がある。

左再帰の除去

脚注

外部リンク

Related Articles

Wikiwand AI