正規LR法

From Wikipedia, the free encyclopedia

計算機科学において、正規LR法LR(1)法正規LR構文解析器LR(1)構文解析器とは、k=1の場合におけるLR(k)、すなわち、終端記号1つを先読みする構文解析手法/構文解析器である。この手法の特徴は、k>1であるすべてのLR(k)構文解析器がLR(1)構文解析器に変形できるということにある[1]。そのため、LR(1)法はすべての決定性文脈自由言語を扱うことができる[1]。かつてこのLR(k)法は巨大なメモリを必要とするために、LALR法LL(1)法のようなLR(k)法ほど強力ではない代替手法が選ばれ、使用を避けられてきた。しかし、近年、空間計算量がLALR法ほどである「最小LR(1)法」がいくつかのパーサジェネレータで採用されてきている。

ほとんどの構文解析器と同様に、LR(1)構文解析器は、GNU Bison、MSTA、Menhir[2]、HYACC[3]、 そして、LRSTAR[4]のような、パーサジェネレータで自動生成することができる。

1965年、ドナルド・クヌースはLR(k)法(入力を左(Left)から右に読んでいき、右端導出 (Rightmost derivation) を行う構文解析手法)を考案した。これはshift-reduce構文解析の一種であり、既存の順位構文解析の一般化である。この手法はすべての決定性文脈自由言語を認識できる可能性があり、入力ファイルにおいて遭遇した文の左導出と右導出の両方を生成できる。クヌースはこの手法の言語認識能力がk=1で最大に達することを証明し、k>1のLR(k)文法をLR(1)文法に変形する手法を与えた[1]

正規LR(1)法は構文解析表の内部表現に膨大なメモリを必要とするという実用上の欠点を抱えている。1969年、Frank DeRemerはLR法についてLALR法およびSLR法と呼ばれる2種類の簡易版を提案した。これらの手法は正規LR(1)法よりも大幅に少ないメモリで解析できるが、言語認識能力はやや劣る[5]。LALR(1)法はLR法の最も一般的な実装である。

しかし、1977年、新しい方式のLR(1)法(最小LR(1)法)が、メモリ要件がLALR(1)法に匹敵するLR(1)法を作成できることを示したDavid Pagerによって考案された[6]。近年、最小LR(1)法を採用するパーサジェネレータも出てきているが、この手法はメモリ要件問題だけでなく、LALR(1)パーサジェネレータ特有の不可思議な衝突問題をも解決する。

概要

LR(1)法は決定性オートマトンを用いているが、オートマトンとしての動作は静的な状態遷移表に基づいている。状態遷移表はオートマトンが認識する言語の文法をコード化しており、概して「構文解析表」と呼ばれる。

LR(1)法の構文解析表は先読みと比較される終端記号によってパラメータ化される。単純な構文解析表(LR(0)法で用いられるようなもの)は以下の形式で文法規則を表現する。

A1A, B

これは、状態Aから状態Bに遷移したならば、次に状態A1に遷移することを意味する。このような規則を先読みによってパラメータ化すると、次を得る。

A1A, B, a

これは、先読みされた終端記号がaであったときのみ遷移が発生することを意味する。これによって、先読みされた文脈によって単純な規則が多様な意味をもつようなより豊かな言語を考慮できる。例えば、LR(1)文法では、同じ状態系列に基づいているにもかかわらず、以下のすべての規則が別の異なる状態へ遷移する。

A1 → A, B, a
A2 → A, B, b
A3 → A, B, c
A4 → A, B, d

先読みされた終端記号を考慮しなかった場合、同じことは当てはまらない。構文解析エラーについては、エラーとする規則を宣言することで構文解析器が入力全体を読み取ることなく識別できる。例えば、

E1 → B, C, d

は構文解析器の停止を引き起こすようなエラーであると宣言できる。これは以下の例のように、先読み情報もまたエラーを補足するために使用できることを意味する。

A1 → A, B, a
A1 → A, B, b
A1 → A, B, c
E1 → A, B, d

この場合、AおよびBは先読みされた終端記号がa、b、またはcならばA1に還元され、dの場合はエラーが報告される。

先読みはまた規則をいつ還元すべきかの決定にも役立つ。先読みは先読みされた記号が有効でない場合にその規則での還元の回避を支援できる。これは現在の状態を以前の状態ではなく次の状態と結合させるべきであるということをおそらく意味する。例えば、以下のような状況である。

  • 状態系列: A, B, C
  • 規則:
A1 → A, B
A2 → B, C

もし、構文解析器が状態Bに遷移した後の先読みが受理可能でなかった場合、つまり、遷移規則が存在しなかった場合、状態系列は

A1, C

ではなく、次のように還元される。

A, A2

なお、状態は次のように終端記号から直接生成できることに注意する必要がある。

X → y

これは出現する状態系列を考慮に入れる。

LR(1)法は個々の規則が完全なLR(1)の方法で表現される必要があるという要件がある。つまり、特定の先読みをもつ2つの状態からなる系列である。これによって、

X → y

のような単純な規則は、先読みと比較される終端記号と状態のすべての可能な組み合わせを本質的に列挙する非常に多数の不自然な規則を要求する。類似の問題は

A1 → A, B

のような非先読み規則の実装にも現れ、すべての可能な先読みの列挙が必要となる。このため、LR(1)法は著しいメモリ最適化なしでは実用的な実装が不可能である[6]

LR(1)構文解析表の作成

参考文献

外部リンク

Related Articles

Wikiwand AI