コンパイラー作成の遊び場

「Create Your Own Compiler」は、JavaScript を Lisp に変換する独自の単純なコンパイラを作成する方法を順を追って説明するインタラクティブなチュートリアルです。 それに加えて、コンパイラが実際に何であるか、および Roslyn の最先端を見ていきます。

コンパイラは重要ですが、ほとんどの人は、コンパイラを使わずに、お気に入りのプログラミング言語とツールを使用して毎日を過ごしています。
それらについて考えすぎて、隠れて何が起こっているのかを無視しています。

しかし、そのブラック ボックスをのぞいて、コンパイラの書き方を学ぶと、超能力が得られます。 カスタム ツールを作成したり、最小限の言語/DSL を作成したり、独自の本格的な言語を作成したり、「独自のコンパイラを作成する」のように、ある言語を別の言語に変換したりできます。

後者、つまりトランスパイルが不可欠であることが証明された理由の代表的な例は、バベルの場合です。 すべてのブラウザーがすべての最新の Javascript 言語機能に対応できるわけではないため、Babel はその最新の Javascript コードを、現在および古いブラウザーまたは環境で後方互換性のあるバージョンの JavaScript に変換します。

さらに別の例は、オプションの型付けを Javascript に追加する Typescript の場合です (これについては、Sorbet – Making Ruby Statically Typed も確認してください)。静的に型付けされ、より優れたスーパーセットとして機能します。 TypeScript コンパイラは、TypeScript コードを分析して JavaScript にコンパイルし、任意のブラウザで実行できるようにします。 Javascript を実行する VM エンジンが存在するため、独自の言語をサポートするためにゼロから構築するのではなく、それを再利用してみませんか? 簡単に変換できます!

Fable は、もう 1 つの X-to-Javascript トランスパイラです。 Fable は F# を ES2015 JavaScript にトランスパイルするため、F# で記述されたコードは、JavaScript が実行されている場所 (ブラウザー、Node.js、Electron、React Native、または一般的には V8) で実行できます。

しかし、コンパイラーの最も一般的なアプリケーションは、実行可能なプログラムを作成するために、プログラムが高水準言語から低水準言語に変換することです (C を参照)。

すべてのコンパイラは、明確に定義されたいくつかのフェーズを実行することによって機能します。各フェーズは、最終的に実行可能なコードを生成するまで、前のフェーズの入力を受け取ります。

最初のフェーズは、レクサーと呼ばれる部分によるトークン化です。 文字のストリームを取り、正規表現を使用すると、言語構文に従ってトークンと呼ばれるものにグループ化されます-キーワード関数、演算子など。

次のフェーズは解析です。 パーサーは、レクサーによって作成されたトークンのストリームを取得し、それらを構造 (抽象的な構文ツリー) で表現します。これは、はるかに扱いやすいものです。

次のフェーズは、コンパイラが言語の構文制約とデータ型を考慮するセマンティック分析です。 コードが適切な形式で適切に型付けされていることを確認します。

次のフェーズは、AST を最適化することです。たとえば、ツリー シェーキングなどの手法を使用してデッド コードを排除します。 このフェーズの結果は、中間表現または IR です。 IR 自体は、マシン コードを生成するためにターゲット CPU アーキテクチャに固有の最適化を受けます。

最後のステップは、スタンドアロンの実行可能ファイル (JVM のようなバイトコードで動作し、実行可能ファイルを作成する代わりに IR で動作するランタイム) を生成することです。これは、C プログラミングでは通常のことですが、Java のような高水準言語でさえ、新しいツールが利用可能になりました。は、GraalVM の下で、ネイティブ実行可能ファイルにコンパイルできます。

上記のリストはもちろん単純化されていますが、一般に、入力ソースを取得して目的の出力に変換するために必要な手順は次のとおりです。

  • レキシング
  • 解析中
  • 抽象構文ツリー (AST) の構築
  • 指定された AST の IR コードを生成する
  • 生成された IR コードの最適化
  • マシンコードを生成する

そのようにしたい場合は、新しいプログラミング言語の構文を定義するステップをそれらに追加してください。

「Create Your Own Compiler」プレイグラウンドを使用すると、その複雑なプロセスを簡単に実行できます。 実際には、Jamie Kyle の「The Super Tiny Compiler」(Javascript で書かれた単純なコンパイラ) の注釈付きウォークスルーです。 このチュートリアルの目標は、Lisp ステートメントを Javascript にコンパイルすることです。 その過程で、字句解析、構文解析、変換、およびコード生成のさまざまな段階を経ていきます。

各ステージは複数のステップに分割され、各ステップには注釈付きのコードがインタラクティブに付属しています。 足を濡らし、裸の概念を把握するのに最適な方法です。

コンパイラを構築するもう 1 つのポストモダンな方法は、Roslyn 方式を採用することです。 その言語でその言語のコンパイラを作成しますか? Microsoft は、最先端のコンパイラ プラットフォームである Roslyn を使用してそれを実現しました。

Roslyn が実際に何であるかという質問に関しては、Roslyn チームのメンバーであり、有名な C# の第一人者である Eric Lippert による信頼できる回答を得ること以上に良いことはありません。 この機会は、2014 年に彼が私たちに返してくれたインタビューの形で生まれました。

NV: Roslyn の公式な定義は、「Visual Basic と C# のコンパイラと言語サービスをそれぞれのマネージ コード言語で完全に書き直すプロジェクトであり、Visual Basic は Visual Basic で書き直され、C# は C# で書き直されている」と述べています。
C# は C# でどのように書き直されていますか?

エル: 私がマイクロソフトにいたとき、非常に多くの人が独自の小さな C# パーサーや IDE、小さなミニ コンパイラなどを独自の目的で作成しているのを見ました。 これは非常に難しく、時間と費用がかかり、正しく行うことはほとんど不可能です。 Roslyn は、C# および VB 用の分析ツールのライブラリをすべての人に提供することで、すべてを変更します。これは、正確で非常に高速で、ツール ビルダーの作業を改善するために特別に設計されています。 私はそれがほぼ完成したことに非常に興奮しています! 私は何年もそれに取り組んできましたが、リリースバージョンを手に入れるのが待ちきれません.

Eric の残りのコメントを読むには、このリンクをクリックしてください。

Roslyn を使用してコンパイラを構築すると、明確な利点が得られます。

  • 動的オブジェクトを処理するための大幅なパフォーマンスの向上と組み込みメカニズム。 コードの発行、アセンブリの解析、およびアセンブリの移植性と、C# でのみ使用可能なツール (コード分析、VS 拡張機能) との統合の可能性をもたらすコンパイラ自体の構造のための重要な機能。
  • Roslyn は Mono および . NET コア。
  • Visual Studio の統合と、コードの色付け、構文の強調表示、IntelliSense などのその他の機能。

魔法!

詳しくは

独自のコンパイラを作成する

関連記事

C# Guru – Eric Lippert へのインタビュー

Fable – F# で Web 用のフロントエンド アプリを作成する

Sorbet – Ruby を静的に型付けする

実用的で軽量な言語を作成する方法

Cornell の CS 6120 Advanced Compilers を無料で入手

I Programmer の新しい記事について通知を受けるには、毎週のニュースレターにサインアップし、RSS フィードを購読して、フォローしてください。 ツイッター、 Facebook または Linkedin。

バナー

ピコブック

コメント

または、コメントを電子メールで送信してください: comments@i-programmer.info

.

Leave a Comment

Your email address will not be published. Required fields are marked *