「文脈自由文法」という用語で「文脈自由」とはどういう意味ですか?


55

文脈自由文法(CFG)が何であるかを説明しようとする資料の量を考えると、そのような文法が「コンテキスト-自由"。そして、私の考えでは、誰もそうすることに成功していません。

私の質問は、なぜ文脈自由文法が文脈自由と呼ばれるのですか?「コンテキスト」とは何ですか?コンテキストは、現在分析されている構造を取り巻く他の言語構造である可能性があるという直感がありましたが、そうではないようです。誰でも正確な説明を提供できますか?


4
コンテキストフリー性が便利な理由を教えてくれるC ++の「最も厄介な構文解析」を調べる
ラチェットフリーク14

6
Googledの定義を読むまで、文脈自由文法とは何かを知っていると思いました。今、私はエッチとスケッチのソフトブランキーがあればいいのに...たぶん私は外に出ます...良い質問のために+1。わかりやすい答えを楽しみにしています!
ブライアン14

「現在分析されているコンストラクトを取り巻く他の言語コンストラクト」の正式な定義が適切でない場合でも、あなたの直感は私が理解していることです。しかし、私はないんだけど確かな答えとして、それを投稿するには十分。
テラスティン14

1
文脈自由文法チョムスキー階層に関するwikiページをご覧ください。実践プログラミング言語で構文解析は、 いくつかのコンテキストを持って、多くの場合、いくつかのシンボルテーブルなどによって、「文脈自由」(LRまたはLL)の解析、の「外」扱いの属性、または環境
バジーレStarynkevitch

1
ここに、xkcd参照があります:xkcd.com/1090
CaptainCodeman

回答:


60

それは、そのすべての意味生成規則は、単一の持っている端末以外の自分の左側を。

たとえば、一致する括弧の文字列( "()"、 "()()"、 "(())()"、...)を認識するこの文法は、コンテキストに依存しません。

S → SS
S → (S)
S → ()

すべてのルールの左側は、単一の非終端記号で構成されます(この場合は常にSですが、もっとあります)。

次に、{a ^ nb ^ nc ^ n:n> = 1}の形式の文字列を認識するこの他の文法を考えてみください(例: "abc"、 "aabbcc"、 "aaabbbccc"):

S  → abc
S  → aSBc
cB → WB
WB → WX
WX → BX
BX → Bc
bB → bb

B非終端記号の前にterminal / literal characterが付いている場合、cその用語をに書き換えますWBが、前bにある場合はに展開しbbます。これはおそらく、文脈依存文法の文脈依存性が示唆していることです。

コンテキストフリー言語は、プッシュダウンオートマトンとして認識できます。有限状態マシンは補助ストレージを使用しません。つまり、その決定は現在の状態と入力のみに基づいていますが、プッシュダウンオートマトンにはスタックがあり、スタックの最上部を見て決定を下すことができます。

動作を確認するには、左から右に移動して左かっこをスタックにプッシュし、右かっこを開くたびにポップすることで、ネストされたかっこを解析できます。空のスタックからポップしようとして決して終了せず、スタックが文字列の最後で空の場合、文字列は有効です。

状況依存言語の場合、PDAでは十分ではありません。テープが無制限ではないチューリングマシンのような線形境界オートマトンが必要になります(ただし、使用可能なテープの量は入力に比例します)。それはコンピュータをかなりよく説明していることに注意してください-私たちはそれらをチューリングマシンと考えるのが好きですが、現実の世界ではプログラム中にRAMを勝手につかむことはできません。LBAがPDAよりも強力であることが明らかでない場合、LBAはテープの一部をスタックとして使用することでPDAをエミュレートできますが、他の方法でテープを使用することもできます。

(有限状態機械が何を認識できるか疑問に思っているなら、答えは正規表現です。しかし、プログラム言語で見られるキャプチャグループと後読み/先読みを伴うステロイドの正規表現ではありません。以下のような事業者と[abc]|*+、と?。あなたはそれを見ることができるabbbz正規表現にマッチするab*zだけで文字列と正規表現であなたの現在の位置を維持することによって、何のスタックは必要ありません。)


14
非常に良い説明。ただし、チューリングマシンのテープは無限である必要はなく、無制限である必要があります。どちらかの端にテープ工場があり、マシンがそれにぶつかると、単にテープを増やします。そうすれば、いつでも有限です。
マイクダンラベイ14

2
@MikeDunlavey説明をありがとう、修正しました。
ドーバル14

10
しかし、テープ工場は、材料を作る無限のテープ、または材料を作る無限のテープを作る材料、または... [スタックオーバーフローを]必要があるだろう
flamingpenguin

8
@Mehrdad:2つのスタックを使用して、任意の数のスタックをシミュレートできます。すべてのスタックを1つのスタック上に積み重ねて保持し、さらにスタックにアクセスする必要がある場合は、上のスタックをポップして2番目のスタックにプッシュします。これは、n> 2スタックが2スタックよりも強力ではないことを証明しています。今、2つのスタックが1つのスタックよりも強力かどうかはわかりません。私の直感はノーと言っていますが、それはスタックプリミティブが何であるかによって異なります。
ヨルグWミットタグ14

10
@JörgWMittag:2つのスタックはテープと同等です。手で振る:現在の位置に対して、一方のスタックをテープの左側として使用し、もう一方のスタックを右側として使用します。したがって、2-PDAはチューリングマシンです。プリミティブの場合、1つのスタックから値をポップし、それを他のスタックにプッシュできる必要があります。これが、テープに沿って移動する方法です。
スティーブジェソップ14

20

他の答えは、正確で正しい場合でも、非常に長くなります。これは短いバージョンです。

文字(文字列と非文字列)の文字列があり、文字列内の非文字列を置換したい場合、文脈自由文法により、非文字列を囲む文字に関係なくそれを行うことができます。

次のルールを考慮してください(小文字は端末、大文字は非端末):

A -> a
AB -> a

最初のルールでは、A 周囲に表示されるもの(コンテキスト)に関係なく、を置き換えることができます。2番目のルールでは、後にが続かないA限り置換できませんB。その場合、両方の非終端記号が置き換えられますが、重要な点は、A問題を囲む非終端記号です。一つは、交換することはできませんBAa、またはBa:のみAが続くBためので、コンテキスト非終端記号のが重要です。つまり、2番目のルールでは非終端記号のコンテキストが重要であり、コンテキストに依存しますが、最初のルールはコンテキストに依存しません。


これは本当に良い説明ですが、その正確性や完全性を保証する資格はありません。これですべてですか?
リック14

1
コンピューター文法はチョムスキー階層の一部です。その記事は開始するのに適した場所です。また、このトピックコンピューターサイエンスの学士号プログラムの一部である必要があります。少なくとも、私たちプログラマーが遭遇する可能性のある圧倒的多数の言語を構成しているので、大学は通常の文脈自由文法を教えるべきです。

@Snowman:あなたがいることを言えば、非常にcrisp.Itが良いだろう「あなたに引き出すことができないaからABしない限りA続いているB代わりに言って、 『あなたは置き換えることはできませんA』は、実際にあなたが交換しているので、可能ではないかもしれませんABではありませんそれ?
ジャスティン

@ジャスティン正しい。これをより明確にするために、答えを更新しました。

@Snowman:あなたは交換することを意味しますAAB?二番目のルール(文脈依存)で、私はあなたがまだ取り替えるしようとしていると思いますAあなたの答えから言ったように。
ジャスティン

7

区別と用語をよりよく理解するために、n b nのような文脈自由言語とa n b n c nのような文脈依存言語を対比することは良い考えです。(表記:a、b、およびcはここではリテラルであり、指数nはリテラルをn回繰り返すことを意味します。たとえば、n > 0です。)たとえば、aabbcまたはaabbbcc後者の言語ではないのに対してaabbccisです。

文脈自由言語のためのアクセプターは、n個のb nが対を契約することができますab、かかわらず(すなわちかかわらず、ABが出現する文脈の)その周りに何、それは言語での文字列のみを受け入れ、何かを拒否し、正しく機能しますすなわち、文法はS -> aSb | abです。プロダクションの左側には端末ないことに注意してください。(2つのプロダクションルールがありますが、簡潔に記述しているだけです。)アクセプタは基本的に、コンテキストに依存しないローカルな決定を行うことができます。

これとは対照的に、あなたは文脈依存言語のためにそのような何かを行うことができないのn B nは C nは、後者のためにあなたは何とかあなたがたコンテキストを覚えておく必要がありますので、あなたが収縮して、それらを一致させるために行う、すなわちどのように多くのABの収縮、 bcの。後者の言語の文法は

S -> abc | aBSc
Ba -> aB
Bb -> bb

最後の2つのルールでは、左側に端末と非端末の両方があることに注意してください。左側の端末は、非端末を展開できるコンテキストです。


「契約」と「拡張」の用語などに関するブートノート:正式な文法は(正式に、はは)生成されますが、パーサーで実際に実装される方法は、実際には還元主義者です。 「逆に」ルールを適用するため、上記の最初の文法でさえプログラムでは実用的ではありません(適用するルールを決定できないため、有名なshift-reduceコンフリクトを与えます)が、上記の2つは文脈自由と文脈依存の区別を説明するには、文法で十分です。文脈自由文法のあいまいさの問題はかなり複雑であり、実際にはこの質問のトピックではないので、特にウィキペディアにはそれに関するまともな記事があることがわかりますので、ここではこれ以上述べません。。対照的に、文脈自由に関する記事、特に文脈依存言語に関する記事は、特にトピックに慣れていない場合は!@#$ @!#$です。これは私のTODOリストにあると思います。


5

上記の答えは、それが何であるかについてかなり良い定義を与えます。20個ではなく23個の説明ができるように、自分の言葉で説明できるかどうかを見てみましょう。文法のすべての目的は、特定の文が特定の言語の文であるかどうかを把握することです。ただし、実際に文法と構文解析を使用するのは、文の意味を理解することです。これは、学校で英語のクラスに戻った、または行っていない文の古い図表のようなものです。文は主語部分と述語部分で構成され、主語部分には名詞とおそらく形容詞があり、述語部分には動詞とおそらく目的語名詞があり、さらに形容詞があります。

英語の文法がある場合(そして、コンピューターサイエンスの意味ではないと思う)、次の形式の規則があります。

Sentence -> SubjectPart PredicatePart
SubjectPart -> Adjective Noun

等...

その後、プログラムを作成して任意の文を渡すことができます。プログラムは文法を使用して、各単語が文のどの部分であり、どのような関係があるかを把握できます。

すべてのプロダクションで、左側に1つしかない場合、それは、文の右側を見るたびに、左側で置き換えることが許可されることを意味します。たとえば、形容詞の名詞を見たときはいつでも、そのフレーズ以外の部分に注意を払うことなく「That's a SubjectPart」と言うことができます。

ただし、英語(上記の簡単な英語の説明でも)は状況依存です。「形容詞名詞」は常にSubjectPartではなく、PredicatePartのNounPhraseである可能性があります。コンテキストに依存します。疑似英語の文法を少し拡張してみましょう。

Sentence -> SubjectPart PredicatePart
SubjectPart -> Adjective Noun
PredicatePart -> VerbPhrase ObjectNounPhrase
VerbPhrase ObjectNounPhrase -> VerbPhrase Adjective Noun

VerbPhraseの直後に来る場合のみ、ObjectNounPhraseに「形容詞」を作成できます。

基本的に、プロダクションがあり、それを囲むものに関係なく、いつでも好きなときにそれを適用できる場合、それはコンテキストフリーです。

文法が文脈自由であるかどうかはいつでも簡単にわかります。矢印の左側に複数のシンボルがあるかどうかを確認してください。

どの言語も複数の文法で記述される場合があります。言語の一部の文法が文脈自由である場合、その言語は文脈自由です。一部の言語では、文脈に依存しない文法が不可能であることが証明できます。上記で説明した簡略化された擬似英語サブセットには、文脈自由文法があるかもしれません。

なぜそれが重要なのかについては、文脈自由文法を解析するために、より単純な種類のプログラムが必要です。他の回答で述べたように、コンテキストなしの文法を解析するのにチューリングマシンの全能力は必要ありません。特定の文脈自由文法の先読みLR(1)パーサー(一種のプッシュダウンマシン)は、その文法内の文を文の長さに比例する時間と空間で解析できます。文が言語内にある場合、パーサーは、文内の各記号が何を意味するか(または少なくとも構造内でどの部分を再生するか)を識別する構造ツリーを生成します。文が文法にない場合、パーサーは最初のシンボルに気付き、停止します。これは、文法および前のシンボルと一致することは不可能です(最初の「エラー」)。

さらに良いのは、文法の説明と、各パートの処理に関する指示のリスト(ある意味で各制作に「意味」を付加する)を提供できるプログラムがあり、プログラムがパーサーを作成することです。あなたのために。プログラムは文を解析し、構造を見つけ、構造の各部分で命令を実行します。この種のプログラムは、パーサージェネレーターまたはコンパイラコンパイラと呼ばれます。

この種の言語分析は、自然言語(英語など)の自動分析のために考案されましたが、これはコンピューター言語の分析に最も役立つことがわかりました。言語設計者は、新しい言語をキャプチャする文法を作成し、パーサージェネレーターで実行して、言語を解析し、必要に応じて翻訳、解釈、コンパイル、実行などを行うプログラムを取得できます。

実際、ほとんどの場合、実際にこれを行うことはできません。たとえば、釣り合った括弧は文脈自由言語ですが、使用する前にすべての変数を宣言する必要がある言語は文脈依存です。パーサーはコンパイラーの一部ですが、これらの他の要件を実施するには追加のロジックが必要です。次に、あなたがしなければならないことは、できるだけ多くの言語をキャプチャする文法を書き、それをパーサージェネレーターで実行し、その後、残りの要件(シンボルテーブルハンドラーなど)を強制するコードを書くことです。

通常、コンテキスト依存の文法はあまりサポートされていないため、使用しません。状況依存言語のLR(k)パーサージェネレーターに相当するものがあるかどうかはわかりません。はい、チューリングマシン(または線形バインドマシン)は1つを解析できますが、LR(1 )ジェネレーターは、プッシュダウンマシンの解析テーブルを作成します。私の推測では、パーサーの基礎となるテーブルは指数関数的に大きくなるでしょう。いずれにせよ、CSの学生(私と同じように、当時の)は通常、コンテキストに依存しない文法とYACCなどのLR(1)パーサージェネレーターを教えられます。


-1

文脈自由文法は、生産規則の文脈を考慮しません。コンテキストは、端末または非端末のいずれかです。

したがって:文脈自由文法では、生成規則の左側に非終端記号が1つしかありません。


3
これは既存の回答に何を追加しますか?また、左側に2つ以上の非端末があるプロダクションルールもコンテキストに依存しません。

与えられた答えは長すぎると思います。TL; DRを追加する場合は、これを削除します。
マーティントーマ14

いいね!「コンテキスト」は、各プロダクションルールを適用できるときに修飾される追加の文字であると言いますか?
リック14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.