言語処理系入門1～言語処理系とは～（勉強メモ）

このシリーズは自分の勉強の形跡のために残したメモとなります。間違いを正すことも目的の一つなので間違いや違和感があれば何でも指定してください。

今回は言語処理系の定義やその種類に関してメモしていきます。

# 勉強のために参考にしているもの
* [「最新コンパイラ構成技法」Andrew W. Appel (著), 神林 靖 (監修, 編集, 監修), 滝本 宗宏 (編集)](https://www.amazon.co.jp/%E6%9C%80%E6%96%B0%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9%E6%A7%8B%E6%88%90%E6%8A%80%E6%B3%95-Andrew-W-Appel/dp/4798114685)
* [「実践コンパイラ構成法 (電子通信情報系コアテキストシリーズ)」滝本 宗宏 (著)](https://www.amazon.co.jp/%E5%AE%9F%E8%B7%B5%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9%E6%A7%8B%E6%88%90%E6%B3%95-%E9%9B%BB%E5%AD%90%E9%80%9A%E4%BF%A1%E6%83%85%E5%A0%B1%E7%B3%BB%E3%82%B3%E3%82%A2%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E6%BB%9D%E6%9C%AC-%E5%AE%97%E5%AE%8F/dp/433901933X/ref=sr_1_1?s=books&ie=UTF8&qid=1539149260&sr=1-1&keywords=%E5%AE%9F%E8%B7%B5%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9%E6%A7%8B%E6%88%90%E6%B3%95)

# 言語処理系入門シリーズ目次
* [言語処理系とは](https://qiita.com/ogata-k/items/b4a2d0cbf90f246aca14) ←ここ
* [処理系の一連の流れ](https://qiita.com/ogata-k/items/dcaa2bdd437ac16206ad)
* [字句解析フェーズ](https://qiita.com/ogata-k/items/60788a507ee224494fbe)

# （プログラミング）言語処理系とは
言語処理系とはプログラミング言語で書かれたプログラム（すなわちソースコード）を処理して実行可能なプログラムコードへと変換または、処理した後何らかの操作を行うソフトウェアのことを言う。この言語処理系は大きく分けてインタプリンタとコンパイラに分かれる。

## インタプリタ
インタプリタはプログラムを逐次的に解析して実行するプログラムの総称のことです。（参照： [プログラミング言語処理系の基礎 #5](http://kmizu.github.io/hands-on/#/5)）**実行まで請け負うことが特徴**となる。参照先でも指摘されているように「一行ずつ解釈するプログラム」や「一行ずつ機械語に変換するプログラム」ということではありません。このインタプリタ形式の処理系を用いるときのメリットとしてソースコードの変更作業が容易であることがあげられる。これは後で説明するコンパイラのように最後まで変換するのを待ってから実行するのではなく、解釈して実行をするというようにインタプリタが解釈と実行をまとめて行うことで素早くコード変更の結果を確認することができるからである。しかし、愚直に逐次解析して実行しているので実行速度が遅くなるデメリットがある。以上のことからプロトタイプ時に扱われることが多い。
関係があるソフトウェアに

* REPL: ユーザが対話的に入力したコードを読み込み(Read)、そのコードをインタプリタに渡し評価して実行する(Eval)、そしてその結果を表示する(Print)ループ(Loop)のこと。これらの頭文字をとってREPLと名付けられている。先ほどインタプリタと勘違いしやすいと指摘した「一行ずつ解釈するプログラム」はこの対話的に一行程度の短いプログラムを入力して実況することが原因と思われる。
* スクリプト言語: 簡易的な記述方式をもちREPLを用いて実行することが多いプログラミング言語の分類。もちろんスクリプト言語にもREPLを用いない言語もある。

がある。

## コンパイラ
コンパイラとはプログラムを機械語や他のプログラミング言語で書かれたプログラムに変換するソフトウェアのことである。後者をトランスレータやトランスパイラと呼び区別することがある。また、AOT（AheadOfTime、事前）コンパイラや単にコンパイラと書いたときは機械語へと変換するソフトウェアを意味する。コンパイラは一度に他の言語（機械語も含む）に変換するので変更作業を結果に反映するのに時間がかかるが、その後は普通インタプリタより高速に実行できる。その為製品となるソフトウェアを変換するときはインタプリタよりコンパイラで変換することが多い。
今後はこのコンパイラに関することを中心に勉強するのでコンパイラに関する記述が増えると思うが、プログラムの解析はインタプリタと共通しているので応用ができるはず。
関係のあるソフトウェアに

* リンケージエディタ（リンカ、連係編集プログラム）： コンパイルによって生成された機械語のプログラムの断片を結合して実際に実行できる形式にまとめるプログラムのこと。詳しくは次の[Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%AA%E3%83%B3%E3%82%B1%E3%83%BC%E3%82%B8%E3%82%A8%E3%83%87%E3%82%A3%E3%82%BF)を参照のこと。
* gcc: GNU Compiler Collection即ち、GNUのコンパイラ群である頭文字の略称である。当初C言語用のコンパイラとして開発されたソフトウェアで今では標準でC、C++、Objective-C、Objective-C++、Fortran、Java、Ada、Go言語のコンパイラ並びにこれらのライブラリを含んでいる。言語によっては名前が変わることもある。
* LLVM: 任意のプログラミング言語に対応可能なコンパイラ基盤である。LLVMはフロントエンド（解析フェーズ）でLLVMに共通する中間コードに変化した後、最適化（最適化フェーズ）によって中間コードの整形や生存解析などを行い、その中間言語をバックエンド（コード生成フェーズ）に渡して各アーキテクチャに応じた機械語を生成する。この各フェーズが独立しているため新しい言語に対応したいときはフロントエンドだけ実装すれば良いし、新しいアーキテクチャに応じたコードを吐き出したいときはバックエンドだけ実装すれば良いのでLLVMは大変便利である。最近の言語はLLVM経由でコンパイラを実装していることがしばしばある。名前の由来は開発初期にLow Level Virtual Machine (低水準仮想機械) の略として名づけられた為。しかし今では何の略ではないただの固有名詞である。詳しくは書籍の[「きつねさんでもわかるLLVM ~コンパイラを自作するためのガイドブック~」柏木 餅子 (著), 風薬 (著)](https://www.amazon.co.jp/%E3%81%8D%E3%81%A4%E3%81%AD%E3%81%95%E3%82%93%E3%81%A7%E3%82%82%E3%82%8F%E3%81%8B%E3%82%8BLLVM-%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9%E3%82%92%E8%87%AA%E4%BD%9C%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%E3%82%AC%E3%82%A4%E3%83%89%E3%83%96%E3%83%83%E3%82%AF-%E6%9F%8F%E6%9C%A8-%E9%A4%85%E5%AD%90/dp/4844334158)を参照のこと。

がある。

## インタプリタ+コンパイラ
もちろん二つを合わせたような処理系も存在する。

関係があるソフトウェアに

* JITコンパイラ: Just In Time(実行時)コンパイラのこと。これは実行するときに入力をして機械語に変換したのち、実行する。その為コンパイラとインタプリタが混ざってはいるが表面上インタプリタとしか見えないソフトウェアとなっている。JITコンパイラを単にコンパイラと呼ぶこともあるが、JIT形式でないコンパイラと区別するときは、機械語を吐くところまで変換するだけのコンパイラのことをAOTコンパイラと呼ぶ。JITコンパイラは実行時に機械語にコンパイルしてから実行するという性質から実行を開始するのが単に機械語を実行するのと比べて遅くなってしまう。しかしコンパイル時に最適化ができている上に機械語で実行できるので、最適化が弱く機械語を模倣して実行しているインタプリタと比べると素早く実行できる。また、実行時に最適化ができることからその目的マシンに応じての最適化もできる為より高速になることもある。

がある。