構文解析

同義語:構文分析parsingsyntactic analysis

概要

構文解析(parsing)とは、文脈自由文法と文字列が与えられたとき、文字列がその文法で生成されるかを判定し、生成されるならその構文木を復元することである。構文木は最左導出と一対一に対応し、Chomsky 標準形の文法では、部分文字列を短い順に調べる CYK 法により、長さ $n$ の文字列の判定・構文木の復元・構文木の個数の計算が $n^{3}$ に比例する手間でできる。規則が次の 1 文字で決まる LL(1) 条件を満たす空語規則のない文法では、予測型の構文解析が入力の長さに比例する手間で働き、文法が曖昧でないことも従う。論理式やプログラムの構文を扱う基礎であり、一意可読性の証明にもなる。

$$\newcommand{C}[0]{\mathbb{C}} \newcommand{div}[0]{\mathbin{÷}} \newcommand{N}[0]{\mathbb{N}} \newcommand{Q}[0]{\mathbb{Q}} \newcommand{R}[0]{\mathbb{R}} \newcommand{Z}[0]{\mathbb{Z}} $$

前提知識: 文脈自由言語, Backus–Naur記法, プッシュダウンオートマトン

計算機に 1-2*3 という式を読ませると、計算機はまず「2*3 を先に計算し、その結果を 1 から引く」という組み立てを文字列から取り出す必要がある。文法が与えられたとき、文字列がその文法で生成されるかを判定し、生成されるならその構文木を復元することを 構文解析(parsing)という。構文解析は、文脈自由言語の理論がプログラミング言語や論理式の処理に使われるときの中心の問題である。
この記事では、構文木と最左導出が一対一に対応することを示したうえで、2 つの方法を扱う。1 つは、Chomsky標準形の文法ならどの文法でも使える CYK 法で、長さ $n$ の文字列を $n^{3}$ に比例する手間で判定し、構文木を復元し、さらに構文木の個数まで数える。もう 1 つは、規則の選び方が次の 1 文字で決まる文法に使える 予測型の構文解析で、入力の長さに比例する手間で働き、文法が曖昧でないことも同時に保証する。

定義

この記事では、文脈自由文法を $G=(V,\Sigma,R,S)$ と書く(文脈自由言語 の定義「文脈自由文法」)。$V$ は非終端記号(変数記号)の有限集合、$\Sigma$ は終端記号の有限集合、$R$ は規則 $A\to\alpha$($A\in V$、$\alpha\in(V\cup\Sigma)^{*}$)の有限集合、$S\in V$ は開始記号である。導出の一歩を $\Rightarrow$、有限回を $\Rightarrow^{*}$ と書き、構文木・完全な構文木・生成文字列・曖昧な文法は 文脈自由言語 の定義「構文木」による。

認識と構文解析

文脈自由文法 $G$ を固定する。文字列 $w\in\Sigma^{*}$ を入力として、$w\in L(G)$ かどうかを判定する問題を $G$ の 認識問題(recognition problem)という。$w\in L(G)$ かどうかを判定し、$w\in L(G)$ ならば根が $S$ で生成文字列が $w$ の完全な構文木を 1 つ出力する問題を $G$ の 構文解析(parsing)といい、これを行う手続きを 構文解析器(parser)という。

導出の順序を 1 つに固定すると、構文木を導出の列として扱える。

最左導出

導出の一歩 $\gamma A\delta\Rightarrow\gamma\alpha\delta$($A\to\alpha\in R$)は、$\gamma\in\Sigma^{*}$、すなわち書き換える $A$ より左に非終端記号がないとき 最左 であるという。すべての一歩が最左である導出を 最左導出(leftmost derivation)といい、$\Rightarrow_{\mathrm{lm}}^{*}$ と書く。

最左導出は、各一歩で使う規則の列だけで決まる。書き換える場所が「いちばん左の非終端記号」と決まっているからである。

構文木と最左導出の対応

$A\in V$、$w\in\Sigma^{*}$ とする。根が $A$ で生成文字列が $w$ の完全な構文木と、最左導出 $A\Rightarrow_{\mathrm{lm}}^{*}w$ とは一対一に対応する。特に、$G$ が曖昧でないことと、各 $w\in L(G)$ の最左導出 $S\Rightarrow_{\mathrm{lm}}^{*}w$ がただ 1 つであることは同値である。

根の規則で分けて帰納法

要点:最左導出では、左の記号から出る部分の書き換えがすべて終わってから右の記号に進むので、最左導出も構文木も「根の規則と、子ごとの部分」に一通りに分かれる。

詳細

準備。 $\beta_1,\beta_2\in(V\cup\Sigma)^{*}$ とし、$\beta_1\beta_2\Rightarrow_{\mathrm{lm}}^{*}w$($w\in\Sigma^{*}$)を最左導出とする。Backus–Naur記法 の補題「導出の分解補題」により、途中の各文字列は $\gamma_1\gamma_2$($\gamma_1$ は $\beta_1$ から、$\gamma_2$ は $\beta_2$ から出た部分)と分かれる。最左の一歩が $\gamma_2$ の中で行われるのは $\gamma_1$ に非終端記号がないとき、すなわち $\gamma_1\in\Sigma^{*}$ のときに限り、その後 $\gamma_1$ は変わらない。よってこの導出は、$\beta_1\Rightarrow_{\mathrm{lm}}^{*}w_1$ の各一歩(右に $\beta_2$ を付けたもの)の後に $\beta_2\Rightarrow_{\mathrm{lm}}^{*}w_2$ の各一歩(左に $w_1$ を付けたもの)を並べたものであり、$w=w_1w_2$ と 2 つの最左導出は導出から一通りに決まる。逆に、そのような 2 つの最左導出を並べたものは最左導出である。記号が $k$ 個の場合も、これを繰り返して同じことが言える。

対応。 $A\Rightarrow_{\mathrm{lm}}^{*}w$ の最初の一歩は、ある規則 $A\to X_1\cdots X_k$ による。準備により、残りの最左導出 $X_1\cdots X_k\Rightarrow_{\mathrm{lm}}^{*}w$ は、分解 $w=w_1\cdots w_k$ と最左導出 $X_i\Rightarrow_{\mathrm{lm}}^{*}w_i$ の組($X_i$ が終端記号なら $w_i=X_i$ で $0$ 歩)と一対一に対応する。一方、根が $A$ の完全な構文木は、根で使う規則 $A\to X_1\cdots X_k$ と、各子 $X_i$ を根とする完全な部分木(生成文字列を $w_i$ とすると $w=w_1\cdots w_k$)の組と一対一に対応する($k=0$ は規則 $A\to\varepsilon$ で $w=\varepsilon$)。したがって、導出の歩数(構文木の頂点数)についての帰納法で、両者は一対一に対応する。最後の主張は、曖昧でないことが「各 $w\in L(G)$ について根が $S$ で生成文字列が $w$ の完全な構文木がただ 1 つ」であることから従う。$\square$

CYK 法

一般の文脈自由文法をそのまま扱うと、空語を生成する非終端記号や、$A\to B$ の形の規則のために、短い部分文字列から長い部分文字列へ順に調べる議論が煩雑になる。そこで規則の形を制限する。

Chomsky標準形の文法

文脈自由文法 $G=(V,\Sigma,R,S)$ のすべての規則が次のいずれかの形であるとき、$G$ は Chomsky 標準形(Chomsky normal form)であるという。

  1. $A\to BC$($A,B,C\in V$、ただし $B\ne S$、$C\ne S$)
  2. $A\to a$($A\in V$、$a\in\Sigma$)
  3. $S\to\varepsilon$

どの文脈自由言語も Chomsky 標準形の文法で生成できる(MSm24 Theorem 3.4.2、pp. 104–109。空語規則の除去・$A\to B$ の形の規則の除去・右辺の分割を順に行う。この記事では証明しない)。空語規則の除去の部分は 文脈自由言語 の命題「空語規則の除去」にある。

Chomsky標準形の導出の形

$G$ を Chomsky 標準形とし、$A\in V$、$w\in\Sigma^{*}$、$A\Rightarrow^{*}w$ とする。

  1. $A\ne S$ ならば $w\ne\varepsilon$ である。
  2. $\lvert w\rvert=1$ ならば $A\to w\in R$ である。
  3. $\lvert w\rvert\ge2$ ならば、規則 $A\to BC\in R$ と分解 $w=yz$($y,z\ne\varepsilon$)で $B\Rightarrow^{*}y$、$C\Rightarrow^{*}z$ となるものがある。
最初の一歩で分ける

1:$S$ はどの規則の右辺にも現れないので、$A\ne S$ から始まる導出に $S$ は現れず、規則 $S\to\varepsilon$ は使われない。残りの規則は文字列を短くしないので、長さは $1$ 以上のままである。
2・3:$A\Rightarrow^{*}w$ の最初の一歩で分ける。規則 $S\to\varepsilon$ なら $w=\varepsilon$ である。規則 $A\to a$ なら $w=a$ である。規則 $A\to BC$ なら、Backus–Naur記法 の補題「導出の分解補題」により $w=yz$、$B\Rightarrow^{*}y$、$C\Rightarrow^{*}z$ と書け、$B,C\ne S$ なので 1 により $y,z\ne\varepsilon$、特に $\lvert w\rvert\ge2$ である。よって $\lvert w\rvert=1$ なら最初の一歩は $A\to w$ であり、$\lvert w\rvert\ge2$ なら最初の一歩は $A\to BC$ の形で 3 の分解がある。$\square$

CYK法

$G=(V,\Sigma,R,S)$ を Chomsky 標準形とし、$w=a_1a_2\cdots a_n$($n\ge1$、$a_i\in\Sigma$)とする。$1\le i\le j\le n$ について集合 $T(i,j)\subset V$ を、$j-i$ についての再帰で
$$ T(i,i):=\{A\mid A\to a_i\in R\},\qquad T(i,j):=\{A\mid A\to BC\in R,\ i\le k< j,\ B\in T(i,k),\ C\in T(k+1,j)\ \text{となる}\ k\ \text{がある}\} $$
と定める。このとき
$$ T(i,j)=\{A\in V\mid A\Rightarrow^{*}a_ia_{i+1}\cdots a_j\} $$
である。特に $w\in L(G)$ であることと $S\in T(1,n)$ であることは同値であり($\varepsilon\in L(G)$ は $S\to\varepsilon\in R$ と同値)、この判定は規則と分割点 $k$ の組を高々 $n^{3}\lvert R\rvert$ 回調べることで行える。

部分文字列の長さについての帰納法

$x_{ij}:=a_i\cdots a_j$ と書き、$U(i,j):=\{A\mid A\Rightarrow^{*}x_{ij}\}$ とおく。$\ell=j-i$ についての帰納法で $T(i,j)=U(i,j)$ を示す。
$\ell=0$ のとき:lem-parsing-cnf-shape の 2 により、$A\Rightarrow^{*}a_i$ は $A\to a_i\in R$ と同値である(逆向きは一歩の導出)。よって $T(i,i)=U(i,i)$ である。
$\ell\ge1$ のとき:$A\in T(i,j)$ なら、規則 $A\to BC$ と $k$ で $B\in T(i,k)$、$C\in T(k+1,j)$ となるものがある。$k-i$ と $j-(k+1)$ は $\ell$ より小さいので、帰納法の仮定により $B\Rightarrow^{*}x_{ik}$、$C\Rightarrow^{*}x_{k+1,j}$ であり、$A\Rightarrow BC\Rightarrow^{*}x_{ik}C\Rightarrow^{*}x_{ik}x_{k+1,j}=x_{ij}$ となるので $A\in U(i,j)$ である。逆に $A\in U(i,j)$ なら、$\lvert x_{ij}\rvert=\ell+1\ge2$ なので lem-parsing-cnf-shape の 3 により、規則 $A\to BC$ と分解 $x_{ij}=yz$($y,z\ne\varepsilon$)で $B\Rightarrow^{*}y$、$C\Rightarrow^{*}z$ となるものがある。$y=x_{ik}$、$z=x_{k+1,j}$ となる $k$ は $i\le k< j$ を満たし、帰納法の仮定により $B\in T(i,k)$、$C\in T(k+1,j)$ なので $A\in T(i,j)$ である。
$w\in L(G)$ は $S\Rightarrow^{*}x_{1n}$ のことなので、$S\in U(1,n)=T(1,n)$ と同値である。$\ell$ の小さい順に $T(i,j)$ を作れば、右辺に現れる $T$ はすでに求まっている。$i\le k< j$ を満たす $(i,k,j)$ の組は $\binom{n+1}{3}\le n^{3}$ 個で、各組で規則を高々 $\lvert R\rvert$ 個調べればよい($\ell=0$ の段の $n\lvert R\rvert$ 回もこの上界に収まる)。$\square$

$T(i,j)$ を求めるときに、$A$ を入れた理由(使った規則 $A\to BC$ と分割点 $k$)を 1 組記録しておけば、$S\in T(1,n)$ のとき $T(1,n)$ の $S$ から理由を逆にたどって構文木を作れる。$T(i,j)=U(i,j)$ の証明が、そのまま作った木が正しい構文木であることを示している。

長さの等しい a と b の列

$\Sigma=\{a,b\}$、開始記号 $S_0$ とし、規則を
$$ S_0\to AB\mid AC,\qquad S\to AB\mid AC,\qquad C\to SB,\qquad A\to a,\qquad B\to b $$
とする。開始記号 $S_0$ は右辺に現れないので Chomsky 標準形である。$S$ と $S_0$ は同じ形の規則をもち、どちらも $\{a^{m}b^{m}\mid m\ge1\}$ を生成する($m$ についての帰納法による)。$w=aabb$ の表は次のとおりである(空欄は空集合)。

$T(i,j)$$j=1$$j=2$$j=3$$j=4$
$i=1$$A$$S_0,S$
$i=2$$A$$S_0,S$$C$
$i=3$$B$
$i=4$$B$

たとえば $T(2,4)$ は、$k=3$ で $S\in T(2,3)$、$B\in T(4,4)$ と規則 $C\to SB$ から $C$ を含む。$T(1,4)$ は、$k=1$ で $A\in T(1,1)$、$C\in T(2,4)$ と規則 $S_0\to AC$ から $S_0$ を含むので、$aabb\in L(G)$ である。

同じ表で、構文木の個数も数えられる。

構文木の個数

thm-parsing-cyk の状況で、根が $A$ で生成文字列が $x_{ij}=a_i\cdots a_j$ の完全な構文木の個数を $N(A,i,j)$ とすると
$$ N(A,i,i)=\#\{\text{規則}\ A\to a_i\},\qquad N(A,i,j)=\sum_{A\to BC\in R}\ \sum_{k=i}^{j-1}N(B,i,k)\,N(C,k+1,j)\quad(i< j) $$
である。特に、$w$ が $G$ において曖昧であるかどうかは $N(S,1,n)\ge2$ かどうかで判定でき、計算の回数の上界は thm-parsing-cyk と同じである。

根の規則と分割点で数える

要点:生成文字列が長さ 2 以上の構文木は、根の規則 $A\to BC$、左の部分木の生成文字列の長さ(分割点 $k$)、2 つの部分木の組で一通りに決まる。

詳細

$i=j$ のとき、lem-parsing-cnf-shape の 2 の証明と同じく、根の規則は $A\to a_i$ でなければならず、その木は規則で決まる。$i< j$ のとき、根の規則は $A\to a$ の形ではありえない(生成文字列が長さ 1 になる)ので $A\to BC$ の形であり、$B$、$C$ を根とする部分木の生成文字列を $y$、$z$ とすると $x_{ij}=yz$、lem-parsing-cnf-shape の 1 から $y,z\ne\varepsilon$ である。$y=x_{ik}$ となる $k$($i\le k< j$)は木から一通りに決まる。逆に、規則 $A\to BC$、$k$、生成文字列が $x_{ik}$ と $x_{k+1,j}$ の部分木の組を与えれば、根の下に並べて構文木ができる。この対応は全単射なので、個数は式のとおりである。

最後に、曖昧であることは根が $S$ で生成文字列が $w$ の完全な構文木が 2 つ以上あることだから、$N(S,1,n)\ge2$ と同値である。$\square$

予測型の構文解析

プッシュダウンオートマトン の命題「文法から機械へ」の機械 $P_G$ は、スタックの一番上の非終端記号 $A$ を規則 $A\to\alpha$ の右辺 $\alpha$ に置き換え、一番上の終端記号を入力の文字と照合する。この機械は使う規則を非決定的に選ぶ。入力の次の 1 文字を見るだけで規則が一通りに決まる文法なら、選択を決定的にでき、手間は入力の長さに比例する。

FIRST集合とLL(1)条件

文脈自由文法 $G$ は、$A\to\varepsilon$ の形の規則をもたないとき 空語規則をもたない という。空でない $\alpha\in(V\cup\Sigma)^{*}$ について
$$ \mathrm{FIRST}(\alpha):=\{a\in\Sigma\mid \alpha\Rightarrow^{*}ax\ \text{となる}\ x\in\Sigma^{*}\ \text{がある}\} $$
とおく。空語規則をもたない $G$ が、各 $A\in V$ と $A$ の相異なる 2 つの規則 $A\to\alpha$、$A\to\alpha'$ について $\mathrm{FIRST}(\alpha)\cap\mathrm{FIRST}(\alpha')=\emptyset$ を満たすとき、$G$ は LL(1) 条件 を満たすという。

空語規則がなければ、$X\in V\cup\Sigma$ から導出される終端記号列は空でないので、$\mathrm{FIRST}(X\beta)=\mathrm{FIRST}(X)$ であり、$\mathrm{FIRST}(a)=\{a\}$ である。各 $\mathrm{FIRST}(A)$ は、空集合から始めて「規則 $A\to X\beta$ ごとに $\mathrm{FIRST}(X)$ を $\mathrm{FIRST}(A)$ に加える」ことを変化がなくなるまで繰り返して求められる(GJ90 §8.2.1、pp. 168–170)。すべての規則の右辺が終端記号で始まり、同じ左辺の規則の右辺の先頭の文字がすべて異なる文法(s 文法、GJ90 §8.1、p. 167)は、LL(1) 条件を満たす。

予測型の手続き

LL(1) 条件を満たす $G$ について、残りの入力 $u\in\Sigma^{*}$ とスタック $\gamma\in(V\cup\Sigma)^{*}$(左端が一番上)の組 $(u,\gamma)$ に、次の一歩を定める。

  1. $\gamma=\varepsilon$ なら停止し、$u=\varepsilon$ のとき受理、そうでなければ拒否する。
  2. $\gamma=a\gamma'$($a\in\Sigma$)なら、$u=au'$ のとき $(u',\gamma')$ に進み(照合)、そうでなければ拒否する。
  3. $\gamma=A\gamma'$($A\in V$)なら、$u=\varepsilon$ のとき拒否する。$u=au'$ のとき、$a\in\mathrm{FIRST}(\alpha)$ となる規則 $A\to\alpha$ があれば(LL(1) 条件により高々 1 つ)$(u,\alpha\gamma')$ に進み(展開)、なければ拒否する。
    $(w,S)$ から始めてこの一歩を繰り返す手続きを、$G$ の 予測型の構文解析(predictive parsing)という。
予測型の構文解析

$G=(V,\Sigma,R,S)$ が LL(1) 条件を満たすとし、$\gamma\in(V\cup\Sigma)^{*}$、$u\in\Sigma^{*}$ とする。

  1. $(u,\gamma)$ から始めた手続きは高々 $(\lvert V\rvert+1)\lvert u\rvert+1$ 歩で停止し、受理するのは $\gamma\Rightarrow^{*}u$ のとき、かつそのときに限る。
  2. 最左導出 $\gamma\Rightarrow_{\mathrm{lm}}^{*}u$ は高々 1 つであり、受理するときは、展開で使った規則を順に並べたものがその最左導出である。
    特に $G$ は曖昧でなく、構文解析は入力の長さに比例する歩数で行える。
最左導出を手続きがなぞる

(a) 最左導出のなぞり。 $D$ を最左導出 $\gamma\Rightarrow_{\mathrm{lm}}^{*}u$ とする。$D$ の歩数と $\lvert\gamma\rvert$ の組について辞書式順序の帰納法で、手続きが $(u,\gamma)$ から $D$ の規則を順に展開して受理することを示す。$\gamma=\varepsilon$ なら $u=\varepsilon$ で受理する。$\gamma=a\gamma'$ なら、先頭の $a$ は書き換わらないので $u=au'$ で、$D$ は最左導出 $\gamma'\Rightarrow_{\mathrm{lm}}^{*}u'$ を与え、手続きは照合して $(u',\gamma')$ に進む。$\gamma=A\gamma'$ なら、$D$ の最初の一歩は最左なので $A$ をある規則 $A\to\alpha$ で書き換える。Backus–Naur記法 の補題「導出の分解補題」により $u=yz$、$\alpha\Rightarrow^{*}y$、$\gamma'\Rightarrow^{*}z$ と書け、空語規則がないので $y\ne\varepsilon$ である。$y$ の最初の文字を $a$ とすると $u=au'$ かつ $a\in\mathrm{FIRST}(\alpha)$ なので、手続きは同じ規則で展開して $(u,\alpha\gamma')$ に進み、残りは歩数の少ない最左導出である。
(b) 受理の正しさ。 手続きが受理するなら、歩数についての帰納法で $\gamma\Rightarrow^{*}u$ である。展開は導出の一歩で、照合は先頭の共通の文字を外すだけだからである。
(c) 停止。 照合は高々 $\lvert u\rvert$ 回である。照合と照合のあいだ(と最初の照合の前)の展開を考える。残りの入力の先頭が $a$ のまま展開が $A_1,A_2,\dots$ と続くとき、$A_{t+1}$ は、$A_t$ の規則のうち $a$ を FIRST に含む唯一のもの $A_t\to\alpha_t$ の右辺の先頭の記号である(先頭が終端記号なら、それは $a$ で次は照合になる)。この「次の記号」を $\nu(A)$ と書く。$A_1$ について $a\in\mathrm{FIRST}(A_1)$ なので $A_1\Rightarrow^{*}ax$ となる導出があり、その構文木の根から一番左の葉 $a$ までの道 $A_1=Y_0,Y_1,\dots,Y_m=a$ では、各頂点の規則の右辺は $Y_{s+1}$ で始まり $a$ を FIRST に含むので、$Y_{s+1}=\nu(Y_s)$ である。もし $A_i=A_j$($i< j$)なら、$\nu$ を繰り返すと $A_i,\dots,A_{j-1}$ を周期的に回り続けて終端記号に達しないが、$Y_0=A_1$ から $\nu$ を繰り返すと $m$ 回で $a$ に達するので矛盾する。よって $A_t$ は相異なり、展開は高々 $\lvert V\rvert$ 回続く。入力を読み終えた後は、一番上が終端記号でも非終端記号でも $1$ 歩で停止する。歩数は合わせて高々 $\lvert u\rvert+\lvert V\rvert\,\lvert u\rvert+1$ である。
(d) まとめ。 $\gamma\Rightarrow^{*}u$ なら、$\gamma=X_1\cdots X_m$ に導出の分解補題を当てて $u=u_1\cdots u_m$、$X_i\Rightarrow^{*}u_i$ と分け、各 $X_i$ の最左導出(prop-parsing-tree-leftmost と 文脈自由言語 の補題「構文木と導出の対応」)を左から順に並べると最左導出 $\gamma\Rightarrow_{\mathrm{lm}}^{*}u$ が得られ、(a) により受理する。逆は (b) である。最左導出は使う規則の列で決まり、(a) により 2 つの最左導出はどちらも決定的な手続きの展開の列に一致するので、等しい。$\gamma=S$ とし prop-parsing-tree-leftmost を使えば、$G$ は曖昧でない。$\square$

Polish 記法の論理式

命題変数 $p_0,p_1,\dots$ と $\lnot,\land,\lor,\to$ を終端記号とし、論理式を結合子を前に置いて括弧なしで書く文法

      <φ> ::= p | ¬<φ> | ∧<φ><φ> | ∨<φ><φ> | →<φ><φ>
    

は s 文法である(p は命題変数を走る。定義では $\Sigma$ は有限なので、命題変数を有限個に限った文法を考える。どの論理式にも命題変数は有限個しか現れないので、以下の結論はすべての論理式に及ぶ)。入力 $\land p_0\lnot p_1$ では、スタックは順に $\varphi$、$\land\varphi\varphi$、$\varphi\varphi$、$p_0\varphi$、$\varphi$、$\lnot\varphi$、$\varphi$、$p_1$、$\varepsilon$ と変わり(展開と照合が交互)、入力も読み終えて受理する。thm-parsing-predictive によりこの文法は曖昧でなく、論理式の読み方は一通りである。これは 一意可読性 の一つの証明になっている。

括弧つきの論理式と左括り出し

Backus–Naur記法 の例「命題論理の論理式」の文法では、$(\lnot\varphi)$ と $(\varphi\land\varphi)$ などの右辺の FIRST がどれも $\{(\}$ なので、LL(1) 条件を満たさない。共通の先頭 ( を括り出して

      <φ> ::= p | ⊤ | ⊥ | ( <ψ>
<ψ> ::= ¬<φ> ) | <φ> <ρ>
<ρ> ::= ∧<φ> ) | ∨<φ> ) | →<φ> )
    

とすると(命題変数は前の例と同じく有限個に限る)、生成する言語は変わらず、$\mathrm{FIRST}(\lnot\varphi))=\{\lnot\}$ と $\mathrm{FIRST}(\varphi\rho)=\mathrm{PropVar}\cup\{\top,\bot,(\}$ は交わらないので LL(1) 条件を満たす。

反例:条件を外すと成り立たない

外す条件反例成り立たなくなること
Chomsky 標準形(thm-parsing-cyk)規則 $S\to A$、$A\to a$、入力 $a$$S\in T(1,1)$ と $a\in L(G)$ の同値
LL(1) 条件(thm-parsing-predictive)規則 $E\to E-E\mid 1$、入力 $1-1-1$曖昧でないこと
空語規則をもたない(thm-parsing-predictive)規則 $S\to Aa$、$A\to a\mid\varepsilon$、入力 $a$受理と $\gamma\Rightarrow^{*}u$ の同値
各行の確かめを開く

1 行目:$A\to B$ の形の規則は Chomsky 標準形にない。$T(1,1)=\{A\mid A\to a\in R\}=\{A\}$ は $S$ を含まないが、$S\Rightarrow A\Rightarrow a$ なので $a\in L(G)$ である。

2 行目:空語規則はないが、$\mathrm{FIRST}(E-E)=\mathrm{FIRST}(1)=\{1\}$ なので LL(1) 条件を満たさない。$1-1-1$ には「$1-1$ と $1$ の差」と「$1$ と $1-1$ の差」の 2 つの構文木がある(Backus–Naur記法 の注意「反例:曖昧な文法」と同じ現象)。

3 行目:$\mathrm{FIRST}(a)=\{a\}$ と $\mathrm{FIRST}(\varepsilon)$(空の右辺から出る空でない文字列はないので空集合とみなす)は交わらず、FIRST の条件は満たす。$L(G)=\{a,aa\}$ で $a\in L(G)$ だが、手続きは $(a,S)$、$(a,Aa)$、$(a,aa)$、$(\varepsilon,a)$ と進み、入力が尽きて拒否する。空語を生成しうる非終端記号があると、次の文字が後ろの記号から来る場合を考えねばならず、FOLLOW 集合を使って手続きを広げる(GJ90 §8.2.2、pp. 170–174)。

補足

  • 左再帰。 $E\to E-T\mid T$ のように $A\Rightarrow^{+}A\beta$ となる非終端記号(左再帰)があると、$T$ が何かを生成する限り $\mathrm{FIRST}(E-T)\supset\mathrm{FIRST}(T)$ となり、LL(1) 条件は破れる。言語を変えずに左再帰を除く変形がある(GJ90 §6.4、p. 128)。
  • 手間の比較。 CYK 法はどの文脈自由文法にも使えるが手間は $n^{3}$ に比例し(GJ90 §4.2.2、pp. 92–94)、予測型の構文解析は手間が $n$ に比例するが使える文法が限られる。実用のプログラミング言語では、LR 法のように、より広い文法の族を入力の長さに比例する手間で扱う方法が使われる(GJ90 §3.6.4、pp. 76–77。この記事では扱わない)。
  • 決定性との関係。 予測型の手続きは、プッシュダウンオートマトン の命題「文法から機械へ」の機械 $P_G$ の動きを 1 文字の先読みで一通りに決めたものである。決定性の機械で受理できない文脈自由言語があるので(プッシュダウンオートマトン の記事の補足「決定性と非決定性」)、すべての文脈自由言語をこの形で解析することはできない。

関連項目

参考文献

[1]
Dick Grune, Ceriel J. H. Jacobs, Parsing Techniques: A Practical Guide, Ellis Horwood, 1990, §3.6.4(線形時間の方法と LR 法)pp. 76–77、§4.2.2(Chomsky 標準形での CYK 法と 3 乗の手間)pp. 92–94、§6.4(左再帰の除去)p. 128、§8.1(s 文法)p. 167、§8.2.1(空語規則のない LL(1) 文法と FIRST 集合の計算)pp. 168–170、§8.2.2(空語規則のある LL(1) 文法と FOLLOW 集合)pp. 170–174

Mathpediaは寄付と、参考文献の書籍リンク(Amazonアソシエイト)の紹介料で運営されています。 支援について / 寄付する