コンピューティングにおいて、コンパイラとは、あるプログラミング言語(ソース言語)で書かれたコンピュータコードを別の言語(ターゲット言語)に変換するソフトウェアのことです。「コンパイラ」という名称は、主に高水準プログラミング言語のソースコードを低水準プログラミング言語(アセンブリ言語、オブジェクトコード、マシンコードなど)に変換して実行可能なプログラムを作成するプログラムに使用されます。[ 1 ] [ 2 ] : p1 [ 3 ]
コンパイラには様々な種類があり、それぞれ異なる有用な形式で出力を生成します。クロスコンパイラは、自身が動作するCPUやオペレーティングシステムとは異なるシステム向けのコードを生成します。ブートストラップコンパイラは、多くの場合、より永続的または最適化されたコンパイラを言語用にコンパイルするために使用される一時的なコンパイラです。
関連ソフトウェアには、低水準言語から高水準言語へ変換するプログラムであるデコンパイラ、高水準言語間で変換するプログラム(通常はソース間コンパイラまたはトランスパイラと呼ばれる) 、言語を変更せずに式の形式を変換するプログラムである言語リライター、そしてコンパイラ(またはその一部)を生成するコンパイラであり、多くの場合、汎用的で再利用可能な方法で多くの異なるコンパイラを生成できるようにするコンパイラであるコンパイラ・コンパイラなどがある。
コンパイラは、前処理、字句解析、構文解析、意味解析(構文指向翻訳)、入力プログラムの中間表現への変換、コード最適化、マシン固有コード生成といった、フェーズと呼ばれる一連の操作の一部または全部を実行することが多い。コンパイラは一般的にこれらのフェーズをモジュール化されたコンポーネントとして実装し、ソース入力からターゲット出力への変換の効率的な設計と正確性を促進する。コンパイラの誤った動作によって発生するプログラムの障害は、追跡して回避することが非常に困難な場合があるため、コンパイラの実装者はコンパイラの正確性を確保するために多大な努力を払う。[ 4 ]
ソースコードを実行可能にするという点では、インタプリタはコンパイラと同様の機能を提供するが、そのメカニズムは異なる。インタプリタはコードを機械語に変換せずに実行する。[ 2 ]: p2したがって、ソースコードを実行するインタプリタもあれば、バイトコードなどの中間形式を実行するインタプリタもある。
ネイティブコードにコンパイルされたプログラムは、インタプリタ方式で実行される場合よりも高速に動作する傾向があります。一方、バイトコードを中間形式とする環境では、中間的な速度になる傾向があります。また、ジャストインタイムコンパイルでは、起動時の処理時間というコストはかかりますが、ネイティブコードの実行速度を実現できます。
アセンブリ言語やC言語などの低レベルプログラミング言語は、特に速度が重要な場合、クロスプラットフォーム対応よりもコンパイルが一般的です。このような言語では、ソースコードと生成されるマシンコードの間に一対一の対応関係が多く存在するため、プログラマーはハードウェアの使用を容易に制御できます。
理論上、どのプログラミング言語もコンパイラまたはインタプリタのどちらでも使用できますが、実際には、言語はどちらか一方のみで使用される傾向があります。とはいえ、一般的にインタプリタ方式で実行される言語のコンパイラを作成することは可能です。例えば、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などの高水準システムプログラミング言語への移行は、いくつかの研究や産業界の取り組みによって始まりました。
BCPL(Basic Combined Programming Language)は、1966年にケンブリッジ大学のマーティン・リチャーズによって設計され、元々はコンパイラ作成ツールとして開発されました。[ 30 ]いくつかのコンパイラが実装されており、リチャーズの著書は言語とそのコンパイラに関する洞察を提供しています。[ 31 ] BCPLは、現在でも研究で使用されている影響力のあるシステムプログラミング言語であるだけでなく[ 32 ]、B言語とC言語の設計の基礎も提供しました。
BLISS(Basic Language for Implementation of System Software)は、WA Wulf率いるカーネギーメロン大学(CMU)の研究チームによって、Digital Equipment Corporation(DEC)のPDP-10コンピュータ向けに開発された。CMUチームは、その1年後の1970年にBLISS-11コンパイラを開発した。
マルチクス(Multiplexed Information and Computing Service)は、 MIT、ベル研究所、ゼネラル・エレクトリック(後にハネウェル)が参加したタイムシェアリングオペレーティングシステムプロジェクトで、MITのフェルナンド・コルバトが主導しました。[ 33 ]マルチクスは、IBMとIBMユーザーグループが開発したPL/I言語で書かれました。 [ 34 ] IBMの目標は、ビジネス、科学、システムプログラミングの要件を満たすことでした。検討できた他の言語もありましたが、PL/Iは実装されていませんでしたが、最も完全なソリューションを提供しました。[ 35 ]マルチクスプロジェクトの最初の数年間は、ベル研究所のダグ・マキルリーとボブ・モリスによる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++ コンパイラが開発されました。
多くのアプリケーション分野において、より高水準の言語を使用するという考え方は急速に広まった。新しいプログラミング言語がサポートする機能の拡大と、コンピュータアーキテクチャの複雑化に伴い、コンパイラもより複雑になっていった。
DARPA(国防高等研究計画局)は1970年にウルフのCMU研究チームと共同でコンパイラプロジェクトを後援した。プロダクション品質コンパイラ-コンパイラPQCC設計では、ソース言語とターゲットの形式定義からプロダクション品質コンパイラ(PQC)を生成することになっていた。[ 44 ] PQCCは、コンパイラ-コンパイラという用語を、パーサー生成器(例: Yacc )という従来の意味を超えて拡張しようと試みたが、あまり成功しなかった。PQCCは、コンパイラ生成器と呼ぶ方がより適切かもしれない。
PQCC のコード生成プロセスに関する研究は、真に自動化されたコンパイラ作成システムの構築を目指した。この取り組みにより、PQC のフェーズ構造が発見され、設計された。BLISS-11 コンパイラが初期構造を提供した。[ 45 ]フェーズには、解析 (フロントエンド)、仮想マシンへの中間変換 (ミドルエンド)、ターゲットへの変換 (バックエンド) が含まれる。TCOL は、中間表現における言語固有の構造を処理するために PQCC 研究用に開発された。[ 46 ] TCOL のバリエーションは、さまざまな言語をサポートした。PQCC プロジェクトは、自動コンパイラ構築の技術を調査した。設計コンセプトは、コンパイラの最適化や (1995 年以降オブジェクト指向) プログラミング言語Adaのコンパイラに役立つことが証明された。
Ada STONEMAN文書[ a ]は、カーネル (KAPSE) および最小構成 (MAPSE) とともに、プログラム サポート環境 (APSE) を正式に規定しました。Ada インタプリタ NYU/ED は、米国規格協会 (ANSI) および国際標準化機構 (ISO) との開発および標準化の取り組みを支援しました。米国軍による初期の Ada コンパイラ開発では、STONEMAN文書に沿って、コンパイラを完全な統合設計環境に組み込みました。陸軍と海軍は、DEC/VAX アーキテクチャを対象とした Ada 言語システム (ALS) プロジェクトに取り組み、空軍は IBM 370 シリーズを対象とした Ada 統合環境 (AIE) の開発を開始しました。これらのプロジェクトは期待された成果をもたらしませんでしたが、Ada 開発全体の取り組みに貢献しました。[ 47 ]
イギリスではヨーク大学、ドイツではカールスルーエ大学で、他の Ada コンパイラ開発の取り組みが始まった。米国では、Verdix (後に Rational に買収) が Verdix Ada Development System (VADS) を陸軍に提供した。VADS は、コンパイラを含む開発ツール一式を提供した。Unix/VADS は、陸軍 CECOM の評価でMotorola 68020をターゲットとしたDEC Ultrix や Sun 3/60 Solarisなど、さまざまな Unix プラットフォームでホストできた。 [ 48 ] Ada 検証テストに合格した Ada コンパイラがすぐに多数利用可能になった。フリー ソフトウェア ファウンデーション GNU プロジェクトは、複数の言語とターゲットをサポートするコア機能を提供するGNU コンパイラ コレクション(GCC) を開発した。Ada 版のGNATは、最も広く使用されている Ada コンパイラの 1 つである。GNAT は無料だが、商用サポートもあり、たとえば AdaCore は、Ada 用の商用ソフトウェア ソリューションを提供するために 1994 年に設立された。 GNAT Proには、GNU GCCベースのGNATと、統合開発環境を提供するツールスイートが含まれています。
高水準言語は引き続きコンパイラの研究開発を牽引しました。重点分野には最適化と自動コード生成が含まれていました。プログラミング言語と開発環境のトレンドはコンパイラ技術に影響を与えました。より多くのコンパイラが言語ディストリビューション(PERL、Java Development Kit)やIDEのコンポーネント(VADS、Eclipse、Ada Pro)に含まれるようになりました。技術間の相互関係と相互依存性が高まりました。Webサービスの出現は、Web言語とスクリプト言語の成長を促進しました。スクリプトは、ユーザーがシステムによって実行されるコマンドを入力できるコマンドラインインターフェイス(CLI)の初期の頃に遡ります。ユーザーシェルの概念は、シェルプログラムを作成するための言語とともに発展しました。初期のWindows設計では、シンプルなバッチプログラミング機能が提供されました。これらの言語の従来の変換には、インタプリタが使用されました。広く使用されていませんが、Bashコンパイラとバッチコンパイラが作成されました。より最近では、高度なインタプリタ言語が開発者のツールキットの一部になりました。現代のスクリプト言語には、PHP、Python、Ruby、Luaなどがあります。(Luaはゲーム開発で広く使用されています。)これらはすべてインタプリタとコンパイラをサポートしています。[ 49 ]
「1950年代後半にコンパイルの分野が始まった当初は、高級言語プログラムを機械語に変換することに焦点が絞られていました。コンパイラ分野は、コンピュータアーキテクチャ、プログラミング言語、形式手法、ソフトウェアエンジニアリング、コンピュータセキュリティなど、他の分野とますます密接に結びついています。」[ 50 ]「コンパイラ研究:次の50年」という記事では、オブジェクト指向言語とJavaの重要性が指摘されています。セキュリティと並列コンピューティングは、将来の研究対象として挙げられています。
コンパイラは、高水準のソースプログラムから低水準のターゲットプログラムへの形式的な変換を実行します。コンパイラの設計では、エンドツーエンドのソリューションを定義することも、プリプロセッサ、アセンブラ、リンカなどの他のコンパイルツールと連携する特定のサブセットを扱うこともできます。設計要件には、コンパイラコンポーネント間の内部インターフェースと、サポートツールセット間の外部インターフェースの両方について、厳密に定義されたインターフェースが含まれます。
初期の頃、コンパイラ設計のアプローチは、処理対象となるコンピュータ言語の複雑さ、設計者の経験、そして利用可能なリソースに直接影響を受けていた。リソースの制約から、ソースコードを複数回処理する必要が生じた。
比較的単純な言語のコンパイラであれば、一人で作成したものであれば単一の巨大なソフトウェアとなるでしょう。しかし、ソース言語が複雑化するにつれて、設計は相互依存する複数のフェーズに分割される可能性があります。これらのフェーズを分けることで、コンパイル処理における機能に開発の焦点を絞った設計上の改善が可能になります。
コンパイラをパス数で分類する背景には、コンピュータのハードウェアリソースの制約がある。コンパイルには多くの処理が必要であり、初期のコンピュータには、これらの処理をすべて行うプログラムを1つだけ格納できるだけのメモリがなかった。そのため、コンパイラはより小さなプログラムに分割され、それぞれがソースコード(またはその表現)を1パスずつ処理し、必要な解析や変換の一部を実行するようになった。
単一パスでコンパイルできる機能は、コンパイラの作成作業を簡素化し、一般的にマルチパスコンパイラよりも高速にソースコードをコンパイルできるため、従来から利点とみなされてきました。そのため、初期システムのリソース制限も一因となり、多くの初期のプログラミング言語は、単一パスでコンパイルできるように特別に設計されました(例:Pascal)。
言語機能の設計によっては、コンパイラがソースコードを複数回処理する必要が生じる場合があります。例えば、ソースコードの20行目にある宣言が、10行目にあるステートメントの翻訳に影響を与える場合を考えてみましょう。この場合、最初の処理では、影響を受けるステートメントの後に続く宣言に関する情報を収集し、その後の処理で翻訳を実行します。
1回のパスでコンパイルするデメリットは、高品質なコードを生成するために必要な高度な最適化を多数実行できないことです。最適化コンパイラが何回パスを実行するかを正確に数えるのは困難です。例えば、最適化の異なるフェーズでは、ある式を何度も解析する一方で、別の式は1回しか解析しない場合があります。
コンパイラを小さなプログラムに分割することは、証明可能な正しさを持つコンパイラの開発に関心のある研究者が用いる手法である。小さなプログラムの集合の正しさを証明する方が、より大きな単一の同等のプログラムの正しさを証明するよりも、多くの場合、労力が少なくて済む。

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

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 ]人間が読めるアセンブリ言語をハードウェアで実行される機械語命令に変換するアセンブラは、コンパイラとはみなされません。[ 70 ] [ b ] (機械語をアセンブリ言語に変換する逆プログラムは、逆アセンブラと呼ばれます。)
コンパイラとは、C言語などの高水準言語(HLL)で書かれたプログラムを同等のアセンブリ言語プログラムに変換するコンピュータプログラムである[2]。
{{cite book}}ISBN /日付の不一致(ヘルプ)コンパイラ構築に関する最初のテキスト。