実際には、最終的にシステムレベルの命令にコンパイル/変換できる言語の場合、コンテキストのない文法である必要がありますか?
例:すべてのプログラミング/スクリプト言語は文脈自由文法ですか?JavaはCFGに基づいていますが、実際にはすべてのプログラミング言語がCFGに基づいているのですか?
必須ではないようですが、私の理解にはギャップがあります。
質問の背景:文法規則も提供するJava言語仕様を見ていました。これは私にこの質問について考えさせました。
実際には、最終的にシステムレベルの命令にコンパイル/変換できる言語の場合、コンテキストのない文法である必要がありますか?
例:すべてのプログラミング/スクリプト言語は文脈自由文法ですか?JavaはCFGに基づいていますが、実際にはすべてのプログラミング言語がCFGに基づいているのですか?
必須ではないようですが、私の理解にはギャップがあります。
質問の背景:文法規則も提供するJava言語仕様を見ていました。これは私にこの質問について考えさせました。
回答:
二回
まず、ほとんどのHPLにはコンテキストがありません。通常、CFGに基づいた構文がありますが、静的セマンティクスと呼ばれるものもあります(多くの場合、構文という用語にも含まれています)。これには、正しいプログラムをチェックアウトする必要がある名前とタイプを含めることができます。例えば、
class A {
String a = "a";
int b = a + d;
}
は構文的に正しいJavaプログラムですが、d
定義されてa
おらず、フィッティングタイプがないためコンパイルされません。
第二に、コンテキストに依存しない言語を解析できます(コンパイラの存在によって明らかに証明されているように)。一般的に、CSGが効率的に解析できないのに対して、CFGは効率的に解析できるだけです。ただし、効率を維持しながら、特定の非コンテキストフリー機能を追加できます。
コンパイラは、多くの場合、フェーズで実行されます。最初のトークン化(通常)、次にコンテキストのない解析、名前と型の分析(コンテキスト依存、場合によってはさらに難しい)。表示されるエラーメッセージの種類によって、その動作を観察できます。
public class Program { public static void main(String[] args) { ... } }
... Javaを使用すると、それほど簡単になりません。:-)
class A { ... }
は、javac
実際に実行できないものをコンパイルするのに完全に十分です(エントリポイントがないため)。しかし、はい。
perlの解析は決定できません。
Pythonの文法が文脈自由であるとは思わない。同じコードブロックの行に同じ量のインデントを設定するという要件は、文脈自由文法がうまく処理するようなものではありません。
より正確には、次の形式のPythonブロックの言語から準同型があるようです。
条件の場合: ライン1 2行目 line3 その他: line4
foo * bar;
あります。宣言は、時間foo
へのポインターbar
または乗算としてですか?foo
bar
Bodo MantheyとMartinBöhmeは、すべてのC ++コンパイラが必然的にチューリング完全であることを示しています。つまり、コンパイル時に部分的な再帰関数を計算できます。そのため、コンテキスト依存よりもはるかに悪いです。
http://wwwhome.math.utwente.nl/~mantheyb/journals/BotEATCS_BoehmeManthey_CompilingCPP.pdf
変数を使用する前の宣言と、OOP言語の関数多型は、コンテキストフリーの文法では処理できないプログラミング言語仕様の他の例だと思います。
int myfun(int a) { ... }
int myfun(int a, int b) { ... }
int myfun(int a, int b, int c, ...) { ... }
...
int I_m_I_cfg = myfun(1,2);
...
私は少しGoogle検索を作って、私はこの記事が見つかりました:「単純なBoolean言語用のブール文法を」 A.Okhotin(2004)によって; 彼によると、本当の問題は、正式な文法で完全に記述されたプログラミング言語を見つけることです。
おもちゃの手続き型プログラミング言語が定義され、 この言語の整形式プログラムのセットのブール文法が構築されます。これは明らかに正式な文法によるプログラミング言語の最初の仕様です。
この記事の「はじめに」セクションは短いですが、非常に明確です。
Cの文法は、パーサーがDuffのデバイスをサポートするために常にコンテキストに依存しないテクニックを使用するという点で、技術的にのみコンテキストに依存すると信じています。
インデントベースの言語は、デイビッドが言ったように自然にコンテキストフリーではありませんが、パラメータ化されたインデントトークンに比べてコンテキストフリーになります。
Haskellでは、infixとinfixlを使用して演算子の優先順位を変更できます。Perlの厳密なプラグマモジュールは、語彙設定$ ^ Hおよび%^ Hを使用して実装されます。これにより、コンテキストフリーではなく、おそらく他の設定も可能になります。
TeXのようなマクロエキスパンダー言語には、実行しないとafaik解析が意味をなさないものがあります。
交差点は文脈自由ではないが、チューリング機械について記述している文脈自由文法もおそらく2つあります。
Javaとアセンブラーは、おそらくどちらも自然にコンテキストフリーです。
(a)-b
Cの文脈依存性の曖昧さはありませんか?(a
変数またはtypedefの可能性があります-他の一部の言語では、この理由で単項マイナス式をキャストできません)
いいえ、実用的な言語の多くはコンテキストに依存しません。たとえば、C ++の文法はそうではありません。コンテキストによっては、文法の解決がコンテキストに依存しない情報の入力に依存するためです。
まず、プログラミング言語の構文と言語自体を区別します。
多くの言語の構文は(少なくとも基づく)Context Free Grammar(CFG)です。これらはよく研究されており、CFGを効率的に解析できるアルゴリズムがあり、CFGで解決できないエッジケースを特別に処理できるためです。
ただし、実際には多くの言語はコンテキストフリーではありません(java、C(++)、Dなどで使用前宣言シンボルが使用されている場合)。
おもしろい事実:Dにはチューリング完全なコンパイル時関数の評価とテンプレートの拡張があり、言語自体をチューリングが決定できないようにしています。しかし、言語の作成者は、構文をCFGにするためにかなりの時間を費やしました。
「すべてのプログラミング/スクリプト言語は文脈自由文法ですか?」一部が関係している、答えは明確なNoです
Re:「最終的にシステムレベルの命令にコンパイル/変換できる言語の場合」という主な質問ですが、なぜCFGである必要があるのかはわかりません。ただし、より良い説明が出てくる可能性があります。
プログラミング言語は、ある種の文法形式に基づいている必要がありますが、CFGはその一例です。CFGが最も一般的です(とuniviersitiesでコンパイラのコースで教えられていつもの事です)が、そのようなあなたはもっとについて読むことができるの解析表現文法、などの他の形式主義があり、ここ(PDF)またはWikipediaでより多くの一口サイズの読み取りのためには。