コンピューティングにおいて、コンパイラとは、あるプログラミング言語(ソース言語)で書かれたコンピュータコードを別の言語(ターゲット言語)に変換するソフトウェアです。「コンパイラ」という名称は、主に、高水準プログラミング言語のソースコードを低水準プログラミング言語(アセンブリ言語、オブジェクトコード、マシンコードなど)に変換し、実行可能プログラムを作成するプログラムに用いられます。[1] [2] : p1 [3]
コンパイラには様々な種類があり、それぞれ異なる有用な形式で出力を生成します。クロスコンパイラは、自身が実行されるCPUやオペレーティングシステムとは 異なるCPUやオペレーティングシステム用のコードを生成します。ブートストラップコンパイラは、多くの場合、一時的なコンパイラであり、特定の言語向けに、より永続的またはより最適化されたコンパイラをコンパイルするために使用されます。
関連ソフトウェアには、低レベル言語から高レベル言語に変換するプログラムであるデコンパイラ、高レベル言語間の変換プログラム(通常はソース間コンパイラまたはトランスパイラと呼ばれる)、言語リライタ(通常は言語を変更せずに式の形式を変換するプログラム)、およびコンパイラ コンパイラ(多くの場合汎用的で再利用可能な方法でコンパイラ(またはその一部)を作成し、多くの異なるコンパイラを作成できるようにするコンパイラ)などがあります。
コンパイラは、前処理、字句解析、構文解析、意味解析(構文に基づく翻訳)、入力プログラムから中間表現への変換、コード最適化、マシン固有のコード生成といった、フェーズと呼ばれる操作の一部またはすべてを実行します。コンパイラは通常、これらのフェーズをモジュールコンポーネントとして実装し、効率的な設計とソース入力からターゲット出力への変換の正確性を促進します。コンパイラの誤った動作によって引き起こされるプログラム障害は、追跡して回避することが非常に困難な場合があります。そのため、コンパイラの実装者は、コンパイラの正確性を確保するために多大な労力を費やしています。[4]
ソースコードを実行可能にするという点では、インタプリタはコンパイラと同様の機能を提供しますが、そのメカニズムは異なります。インタプリタはコードを機械語に変換せずに実行します。[2] : p2 そのため、ソースコードを実行するインタプリタもあれば、バイトコードなどの中間形式を実行するインタプリタもあります。
したがって、ネイティブコードにコンパイルされたプログラムは、インタープリタで実行された場合よりも高速に実行される傾向があります。バイトコード中間形式を使用する環境では、中間速度になる傾向があります。一方、ジャストインタイムコンパイルでは、一度の起動処理にかかるコストを犠牲にして、ネイティブ実行速度を実現します。
アセンブリ言語やC言語などの低水準プログラミング言語は、特に速度が重視される場合、クロスプラットフォーム対応ではなくコンパイルされるのが一般的です。そのため、このような言語では、ソースコードと生成されるマシンコードの間に1対1の対応関係がより多く存在し、プログラマーがハードウェアの使用を制御しやすくなります。
理論上、プログラミング言語はコンパイラまたはインタプリタを介して使用できますが、実際には、各言語はどちらか一方のみで使用される傾向があります。しかしながら、一般的にインタプリタで実行される言語用のコンパイラを作成することは可能です。例えば、Common LispはJavaバイトコードにコンパイルされ(その後Java仮想マシンによってインタプリタ処理されます)、Cコードにコンパイルされ(その後ネイティブマシンコードにコンパイルされます)、または直接ネイティブコードにコンパイルできます。

科学者、数学者、エンジニアによって開発された理論的な計算概念は、第二次世界大戦中のデジタル現代計算の発展の基礎を形成しました。デジタル機器は1と0、そして基礎となるマシンアーキテクチャの回路パターンしか理解できなかったため、原始的なバイナリ言語が進化しました。1940年代後半には、コンピュータアーキテクチャをより実用的な抽象化するためにアセンブリ言語が作成されました。[5]初期のコンピュータはメモリ容量が限られていたため、最初のコンパイラの設計時には大きな技術的課題がありました。そのため、コンパイルプロセスを複数の小さなプログラムに分割する必要がありました。フロントエンドプログラムは、バックエンドプログラムがターゲットコードを生成するために使用する分析製品を生成します。コンピュータ技術がより多くのリソースを提供するにつれて、コンパイラの設計はコンパイルプロセスとよりよく一致するようになりました。
プログラマーにとって、高水準言語を使用する方が生産性が高い場合が多いため、デジタルコンピュータの機能向上に伴い、高水準言語の開発は自然な流れで進みました。高水準言語とは、高水準言語アーキテクチャを構成する 構文と意味論によって厳密に定義された形式言語です。これらの形式言語の要素には、以下のものがあります。
言語における文は、文法と呼ばれる一連の規則によって定義されることがあります。[6]
バッカス・ナウア記法(BNF)は、言語の「文」の構文を記述する記法です。ジョン・バッカスによって開発され、 Algol 60の構文に使用されました。[7]この概念は、言語学者ノーム・チョムスキーの文脈自由文法の概念に由来しています。[8]「BNFとその拡張は、プログラミング記法の構文を記述するための標準的なツールとなっています。多くの場合、コンパイラの一部はBNF記述から自動的に生成されます。」[9]
1942年から1945年にかけて、コンラート・ツーゼはコンピュータ用の最初の(アルゴリズム的)プログラミング言語であるプランカルキュル(Plankalkül、「平面計算」)を設計しました。ツーゼはまた、プログラムの数学的定式化を機械可読なパンチフィルムに自動的に変換するプランフェルティグングスゲレット( Planfertigungsgerät 、「平面組立装置」)を構想しました。[10]実際の実装は1970年代まで行われませんでしたが、後にケン・アイバーソンが1950年代後半に設計したAPLに見られる概念を提示しました。 [11] APLは数学計算のための言語です。
1949年から1951年にかけて、ハインツ・ルティスハウザーは高級言語と自動翻訳機であるスーパープランを提案した。 [12]彼のアイデアは後にフリードリヒ・L・バウアーとクラウス・ザメルソンによって改良された。[13]
デジタルコンピューティングの形成期における高水準言語設計は、さまざまなアプリケーションに役立つプログラミング ツールを提供しました。
コンパイラ技術は、高水準ソースプログラムをデジタルコンピュータ用の低水準ターゲットプログラムへと厳密に定義された変換を行う必要性から発展しました。コンパイラは、ソースコードの解析を行うフロントエンドと、解析結果をターゲットコードに合成するバックエンドとして捉えることができます。フロントエンドとバックエンド間の最適化により、より効率的なターゲットコードを生成することができます。[17]
コンパイラ技術開発における初期のマイルストーンは次のとおりです。
初期のオペレーティングシステムとソフトウェアはアセンブリ言語で書かれていました。1960年代から1970年代初頭にかけては、リソースの制約から、システムプログラミングにおける高級言語の使用は依然として議論の的となっていました。しかし、いくつかの研究と産業界の取り組みにより、BCPL、BLISS、B、Cといった高級システムプログラミング言語への移行が始まりました。
1966年にケンブリッジ大学のマーティン・リチャーズによって設計されたBCPL(Basic Combined Programming Language)は、もともとコンパイラ作成ツールとして開発されました。 [30]いくつかのコンパイラが実装されており、リチャーズの著書では、言語とそのコンパイラに関する洞察が提供されています。[31] BCPLは、現在でも研究に使用されている影響力のあるシステムプログラミング言語であるだけでなく、 [32] B言語とC言語の設計の基礎も提供しました。
BLISS(システムソフトウェア実装用基本言語)は、WA Wulf率いるカーネギーメロン大学(CMU)の研究チームによって、Digital Equipment Corporation(DEC)のPDP-10コンピュータ向けに開発されました。CMUチームは1年後の1970年にBLISS-11コンパイラを開発しました。
Multics (Multiplexed Information and Computing Service) は、 MIT、ベル研究所、ゼネラル・エレクトリック(後のハネウェル)が参加したタイムシェアリング・オペレーティング・システム・プロジェクトで、MIT のFernando Corbatóがリーダーを務めた。[33] Multics は、IBM と IBM ユーザー・グループが開発したPL/I言語で書かれた。 [34] IBM の目標は、ビジネス、科学、システム・プログラミングの要件を満たすことだった。検討できた言語は他にもあったが、PL/I は実装されていなかったものの、最も完全なソリューションを提供した。[35] Multics プロジェクトの最初の数年間は、ベル研究所の Doug McIlory と Bob Morris による Early PL/I (EPL) コンパイラーを使用して、言語のサブセットをアセンブリ言語にコンパイルすることができた。[36] EPL は、完全な PL/I 用のブートストラッピング・コンパイラーが開発されるまでプロジェクトをサポートした。[37]
ベル研究所は1969年にMulticsプロジェクトから離脱し、BCPLのコンセプトに基づいたシステムプログラミング言語Bを開発しました。これはデニス・リッチーとケン・トンプソンによって書かれました。リッチーはB用のブートストラップコンパイラを開発し、 PDP-7用のUnics(Uniplexed Information and Computing Service)オペレーティングシステムをBで記述しました。Unicsは最終的にUnixと綴られるようになりました。
ベル研究所はBとBCPLをベースにCの開発と拡張を開始しました。BCPLコンパイラはベル研究所によってMulticsに移植されており、BCPLはベル研究所で推奨言語でした。[38]当初、Cコンパイラの開発中はベル研究所のBコンパイラのフロントエンドプログラムが使用されました。1971年、新しいPDP-11がBの拡張を定義し、コンパイラを書き直すためのリソースを提供しました。1973年までにC言語の設計は実質的に完了し、PDP-11用のUnixカーネルはCで書き直されました。スティーブ・ジョンソンは、Cコンパイラを新しいマシンに再ターゲットするためのポータブルCコンパイラ(PCC)の開発を開始しました。[39] [40]
オブジェクト指向プログラミング(OOP)は、アプリケーションの開発と保守にいくつかの興味深い可能性をもたらしました。OOPの概念はさらに古くから存在していましたが、LISPとSimula言語科学の一部でした。[41]ベル研究所はC++の開発をきっかけにOOPに興味を持つようになりました。[42] C++は1980年にシステムプログラミングに初めて使用されました。初期の設計では、C言語のシステムプログラミング機能とSimulaの概念が活用されていました。オブジェクト指向機能は1983年に追加されました。[43] Cfrontプログラムは、C84言語コンパイラ用のC++フロントエンドを実装しました。その後、C++の人気が高まるにつれて、いくつかのC++コンパイラが開発されました。
多くのアプリケーション分野において、高水準言語を使用するという考え方が急速に広まりました。新しいプログラミング言語がサポートする機能の拡大と、コンピュータアーキテクチャの複雑さの増大により、コンパイラはより複雑になりました。
1970年、 DARPA(国防高等研究計画局)はウルフのCMU研究チームと共同でコンパイラプロジェクトを後援した。Production Quality Compiler-Compiler PQCC設計は、ソース言語とターゲットの形式定義からProduction Quality Compiler(PQC)を生成するものであった。[44] PQCCは、コンパイラ-コンパイラという用語を、従来のパーサージェネレータ( Yaccなど)の意味を超えて拡張しようとしたが、あまり成功しなかった。PQCCは、より正確にはコンパイラジェネレータと呼ぶべきかもしれない。
PQCC のコード生成プロセスの研究では、真に自動化されたコンパイラ作成システムの構築を目指しました。この取り組みにより、PQC のフェーズ構造が発見され、設計されました。BLISS-11 コンパイラが最初の構造を提供しました。[45]フェーズには、分析 (フロントエンド)、仮想マシンへの中間変換 (ミドルエンド)、ターゲットへの変換 (バックエンド) が含まれます。TCOL は、中間表現で言語固有の構成要素を処理するために PQCC 研究用に開発されました。[46] TCOL のバリエーションはさまざまな言語をサポートしました。PQCC プロジェクトでは、自動コンパイラ構築の手法を調査しました。設計コンセプトは、コンパイラの最適化や、(1995 年以降はオブジェクト指向) プログラミング言語Ada用のコンパイラに役立つことが証明されました。
Ada STONEMAN文書[a]は、プログラム支援環境(APSE)に加え、カーネル(KAPSE)と最小限の環境(MAPSE)を公式化した。AdaインタープリタであるNYU/EDは、米国規格協会(ANSI)および国際標準化機構(ISO)との開発・標準化活動を支援していた。米軍による初期のAdaコンパイラ開発には、STONEMAN文書に沿った完全な統合設計環境に組み込まれたコンパイラが含まれていた。陸軍と海軍はDEC/VAXアーキテクチャを対象としたAda言語システム(ALS)プロジェクトに取り組み、空軍はIBM 370シリーズを対象としたAda統合環境(AIE)に着手した。これらのプロジェクトは期待された成果をもたらさなかったものの、Ada開発全体の取り組みに貢献した。[47]
その他の Ada コンパイラの開発は、イギリスのヨーク大学やドイツのカールスルーエ大学でも始まりました。米国では、Verdix (後に Rational に買収された) が陸軍に Verdix Ada 開発システム (VADS) を提供しました。VADS はコンパイラを含む開発ツールのセットを提供しました。Unix/VADS は DEC Ultrix や、陸軍 CECOM 評価で Motorola 68020 をターゲットとした Sun 3/60 Solaris など、さまざまな Unix プラットフォームでホストできました。[48] Ada 検証テストに合格した多くの Ada コンパイラがすぐに登場しました。フリーソフトウェア財団の GNU プロジェクトは、複数の言語とターゲットをサポートするための中核機能を提供するGNU コンパイラ コレクション(GCC) を開発しました。Ada バージョンのGNATは、最も広く使用されている Ada コンパイラの 1 つです。GNAT は無料ですが、商用サポートもあり、たとえば AdaCore は 1994 年に Ada 用の商用ソフトウェア ソリューションを提供するために設立されました。 GNAT Pro には、統合開発環境を提供するツール スイートを備えた GNU GCC ベースの GNAT が含まれています。
高水準言語は、コンパイラの研究開発を牽引し続けました。重点分野には、最適化と自動コード生成が含まれていました。プログラミング言語と開発環境の動向は、コンパイラ技術に影響を与えました。より多くのコンパイラが、言語ディストリビューション(PERL、Java Development Kit)やIDE(VADS、Eclipse、Ada Pro)のコンポーネントとして含まれるようになりました。技術間の相互関係と相互依存性が高まりました。Webサービスの出現は、Web言語とスクリプト言語の成長を促進しました。スクリプトは、ユーザーがシステムに実行させるコマンドを入力できるコマンドラインインターフェース(CLI)の初期の時代にまで遡ります。ユーザーシェルの概念は、シェルプログラムを記述するための言語によって発展しました。初期のWindows設計は、シンプルなバッチプログラミング機能を提供していました。これらの言語の従来の変換には、インタープリタが使用されていました。広くは使用されていませんが、BashとBatchコンパイラが開発されました。最近では、洗練されたインタープリタ型言語が開発者ツールキットの一部となっています。最新のスクリプト言語には、PHP、Python、Ruby、Luaなどがあります(Luaはゲーム開発で広く使用されています)。これらはすべて、インタープリタとコンパイラをサポートしています。[49]
「1950年代後半にコンパイルの分野が始まった当初、その焦点は高級言語プログラムを機械語に変換することに限られていました。…コンパイラ分野は、コンピュータアーキテクチャ、プログラミング言語、形式手法、ソフトウェア工学、コンピュータセキュリティといった他の分野とますます密接に絡み合っています。」[50]「コンパイラ研究:今後50年」の記事では、オブジェクト指向言語とJavaの重要性が指摘されています。セキュリティと並列コンピューティングは、将来の研究目標として挙げられています。
コンパイラは、高水準ソースプログラムから低水準ターゲットプログラムへの形式的な変換を実装します。コンパイラ設計では、エンドツーエンドのソリューションを定義することも、プリプロセッサ、アセンブラ、リンカーなどの他のコンパイルツールとインターフェースする定義済みのサブセットに取り組むこともできます。設計要件には、コンパイラコンポーネント間の内部インターフェースと、サポートツールセット間の外部インターフェースの両方において、厳密に定義されたインターフェースが含まれます。
初期のコンパイラ設計のアプローチは、処理対象となるコンピュータ言語の複雑さ、設計者の経験、そして利用可能なリソースに直接影響されていました。リソースの制約により、ソースコードを複数回検証する必要がありました。
比較的単純な言語のコンパイラであれば、一人で書いたものは単一のモノリシックなソフトウェアになるかもしれません。しかし、ソース言語が複雑になるにつれて、設計は相互に依存する複数のフェーズに分割されることがあります。これらのフェーズでは、コンパイルプロセスの機能に重点を置いた設計改善が行われます。
コンパイラをパス数で分類する背景には、コンピュータのハードウェアリソースの限界があります。コンパイルには多くの作業が必要であり、初期のコンピュータには、これらすべての作業を実行するプログラムを1つ格納できるだけのメモリがありませんでした。その結果、コンパイラは小さなプログラムに分割され、各プログラムはソース(またはその表現)をパスすることで、必要な解析と変換の一部を実行しました。
シングルパスでコンパイルできる機能は、コンパイラの作成作業を簡素化し、また、シングルパスコンパイラはマルチパスコンパイラよりも一般的にコンパイル速度が速いため、従来から利点と考えられてきました。そのため、初期のシステムのリソース制限もあって、多くの初期の言語はシングルパスでコンパイルできるように特別に設計されていました(例:Pascal)。
言語機能の設計によっては、コンパイラがソースコードを複数回処理する必要がある場合もあります。例えば、ソースコードの20行目に出現する宣言が、10行目の文の翻訳に影響を与えるとします。この場合、最初のパスでは、影響を受ける文の後に出現する宣言に関する情報を収集し、実際の翻訳は後続のパスで行われます。
シングルパスでコンパイルするデメリットは、高品質なコードを生成するために必要な高度な最適化の多くを実行できないことです。最適化コンパイラが実行するパス数を正確に数えることは困難です。例えば、最適化の異なるフェーズで、ある式は複数回解析される一方で、別の式は1回しか解析されない場合があります。
コンパイラを小さなプログラムに分割することは、証明可能な正しさを持つコンパイラの開発に関心を持つ研究者が用いる手法です。小さなプログラム群の正しさを証明する方が、単一の同等の大きなプログラムの正しさを証明するよりも労力が少なくなることがよくあります。

コンパイラ設計におけるフェーズの正確な数に関わらず、フェーズは3つのステージのいずれかに割り当てることができます。これらのステージには、フロントエンド、ミドルエンド、バックエンドが含まれます。
このフロント/ミドル/バックエンドのアプローチにより、ミドルエンドの最適化を共有しながら、異なる言語のフロントエンドと異なるCPUのバックエンドを組み合わせることができます。 [51]このアプローチの実際の例としては、GNUコンパイラコレクション、Clang(LLVMベースのC/C++コンパイラ)、[52]アムステルダムコンパイラキットなどがあり、これらは複数のフロントエンド、共有最適化、複数のバックエンドを備えています。

if(net>0.0)total+=net*(1.0+tax/100.0);フロントエンドはソースコードを解析し、中間表現(IR)と呼ばれるプログラムの内部表現を構築します。また、ソースコード内の各シンボルを位置、型、スコープなどの関連情報にマッピングするデータ構造である シンボルテーブルを管理します。
フロントエンドは、スキャナレス パーサのように単一のモノリシックな関数またはプログラムにすることもできますが、伝統的には複数のフェーズとして実装および分析され、順次または同時に実行されることがあります。 この方法は、モジュール性と関心の分離のために好まれています。 最も一般的には、フロントエンドは、字句解析(字句分析またはスキャンとも呼ばれる)、構文解析(スキャンまたは解析とも呼ばれる)、および意味解析の3 つのフェーズに分けられます。 字句分析と解析は、構文解析 (それぞれ単語構文と句構文) を構成し、単純なケースでは、これらのモジュール (字句解析器とパーサ) は言語の文法から自動的に生成できますが、より複雑なケースでは手動で変更する必要があります。 字句文法と句文法は通常、文脈自由文法であり、これにより分析が大幅に簡素化され、文脈依存性は意味解析フェーズで処理されます。意味解析フェーズは一般的に複雑で手作業で記述されますが、属性文法を用いることで部分的または完全に自動化できます。これらのフェーズ自体はさらに細分化できます。字句解析はスキャンと評価、構文解析は具体的な構文木(CST、構文木)の構築と抽象構文木(AST、構文木)への変換です。場合によっては、行再構成や前処理などの追加のフェーズが用いられますが、これはまれです。
フロントエンドの主なフェーズは次のとおりです。
ミドルエンドはオプティマイザとも呼ばれ、中間表現に対して最適化を実行し、生成されるマシンコードのパフォーマンスと品質を向上させます。[56]ミドルエンドには、対象となるCPUアーキテクチャに依存しない最適化が含まれています。
ミドルエンドの主なフェーズは次のとおりです。
コンパイラ解析はあらゆるコンパイラ最適化の前提条件であり、両者は密接に連携して動作します。例えば、依存関係解析はループ変換に不可欠です。
コンパイラの分析と最適化の範囲は多岐にわたります。その範囲は、基本ブロック内の動作から、プロシージャ全体、さらにはプログラム全体まで多岐にわたります。最適化の粒度とコンパイルコストの間にはトレードオフがあります。例えば、ピープホール最適化はコンパイル中に高速に実行されますが、コードの小さなローカルフラグメントにのみ影響し、コードフラグメントが出現するコンテキストとは独立して実行できます。一方、プロシージャ間最適化はより多くのコンパイル時間とメモリ空間を必要としますが、複数の関数の動作を同時に考慮することによってのみ実現可能な最適化を可能にします。
プロシージャ間解析と最適化は、HP、IBM、SGI、Intel、Microsoft、Sun Microsystemsなどの最新の商用コンパイラでは一般的です。フリーソフトウェアの GCCは、強力なプロシージャ間最適化が不足していると長年批判されてきましたが、この点は改善されつつあります。完全な解析および最適化インフラストラクチャを備えた別のオープンソースコンパイラはOpen64で、多くの組織で研究目的および商用目的で使用されています。
コンパイラの解析と最適化には余分な時間とメモリが必要となるため、一部のコンパイラではデフォルトでこれらの処理を省略しています。ユーザーは、コンパイルオプションを使用して、どの最適化を有効にするかをコンパイラに明示的に指示する必要があります。
バックエンドはCPUアーキテクチャ固有の最適化とコード生成を担当します。[56]
バックエンドの主なフェーズは次のとおりです。
コンパイラの正確性は、コンパイラが言語仕様に従って動作することを示すソフトウェアエンジニアリングの分野です。[58]技術には、形式手法を使用してコンパイラを開発することや、既存のコンパイラに対して厳密なテスト(コンパイラ検証と呼ばれることが多い)を使用することが含まれます。
高水準プログラミング言語は通常、何らかの翻訳を念頭に置いて設計されており、コンパイル言語またはインタプリタ言語として設計されています。しかしながら、実際には、実行時に再解釈を必要とする言語を設計することは可能ですが、言語がコンパイルのみ、またはインタプリタのみで実行されることを要求するケースは稀です。この分類は通常、言語の最も普及した実装を反映しています。例えば、BASICはインタプリタ言語、Cはコンパイル言語と呼ばれることがありますが、これはBASICコンパイラとCインタプリタが存在するにもかかわらずです。[59]
インタプリタはコンパイルを完全に置き換えるものではありません。コンパイルをユーザーから隠蔽し、段階的に実行させるだけです。インタプリタ自体もインタプリタとして解釈可能ですが、実行スタックの最下部のどこかに、直接実行される機械語命令の集合が必要です(機械語を参照)。
さらに、最適化のためにコンパイラにインタープリタ機能を持たせることができ、インタープリタには事前コンパイル技術が組み込まれる場合があります。例えば、コンパイル中に式を実行し、その結果を出力プログラムに挿入することで、プログラム実行のたびに式を再計算する必要がなくなり、最終的なプログラムの実行速度を大幅に向上させることができます。ジャストインタイムコンパイルやバイトコード解釈といった近年のトレンドは、コンパイラとインタープリタの従来の区分をさらに曖昧にすることがあります。メタトレーシングは、これをさらに発展させた自動コンパイラ合成手法であり、言語インタープリタからコンパイラを合成するために使用できます。
一部の言語仕様では、実装にコンパイル機能を含まなければならないと明記されています。たとえば、 Common Lispです。しかし、Common Lisp の定義には、インタープリタで実行できないようにする固有の要素はありません。他の言語では、インタープリタで実装するのは非常に簡単ですが、コンパイラの作成がはるかに難しくなります。たとえば、APL、SNOBOL4、[60]、および多くのスクリプト言語では、プログラムが実行時に通常の文字列操作を使用して任意のソースコードを作成し、そのコードを特別な評価関数に渡すことで実行できます。コンパイルされた言語でこれらの機能を実装するには、通常、コンパイラ自体のバージョンを含む ランタイムライブラリとともにプログラムが出荷される必要があります。
コンパイラの分類方法の一つは、生成されたコードが実行されるプラットフォームによって分類することです。これはターゲットプラットフォームと呼ばれます。
ネイティブコンパイラまたはホストコンパイラとは、コンパイラ自体が動作するのと同じ種類のコンピュータおよびオペレーティングシステム上で直接実行することを目的とした出力を生成するコンパイラです。クロスコンパイラの出力は、異なるプラットフォーム上で実行されるように設計されています。クロスコンパイラは、ソフトウェア開発環境のサポートを意図していない 組み込みシステム向けのソフトウェアを開発する際によく使用されます。
仮想マシン(VM)用のコードを生成するコンパイラの出力は、それを生成したコンパイラと同じプラットフォーム上で実行される場合とそうでない場合があります。そのため、このようなコンパイラは通常、ネイティブコンパイラやクロスコンパイラとして分類されません。
コンパイラのターゲットとなる低レベル言語は、それ自体が高レベルプログラミング言語である場合があります。C は、ある種の移植可能なアセンブリ言語と見なされることもあり、このようなコンパイラのターゲット言語となることがよくあります。たとえば、C++のオリジナルコンパイラであるCfront は、C をターゲット言語として使用していました。このようなコンパイラによって生成される C コードは、通常、人間が読んだり保守したりすることを目的としていないため、インデントスタイルや見栄えの良い C 中間コードの作成は無視されます。C を優れたターゲット言語にする特徴には、元のソースのデバッグをサポートするためにコンパイラによって生成できるディレクティブや、C コンパイラで利用できる幅広いプラットフォームのサポートなどがあります。
#line
一般的なコンパイラ タイプはマシン コードを出力しますが、他にも多くのタイプがあります。
DOALLステートメント)を付与します。ソース・ツー・ソース・コンパイラは、トランスコンパイラまたはトランスパイラとも呼ばれます。[61]人間が読めるアセンブリ言語をハードウェアで実行される機械語命令に変換するアセンブラは、コンパイラとはみなされません。[69] [b] (機械語をアセンブリ言語に変換する逆プログラムは逆アセンブラと呼ばれます。)
コンパイラは、Cなどの高級言語(HLL)で書かれたプログラムを同等のアセンブリ言語プログラムに変換するコンピュータプログラムです[2]。
{{cite book}}: ISBN / Date incompatibility (help)
{{cite book}}:|website=無視されました (ヘルプ)
コンパイラ構築に関する最初のテキスト。