Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 11591] ファイルの概要

このコミットは、Goコンパイラ(gc)のビルドプロセスにおける重要な変更を導入しています。具体的には、y.tab.cy.tab.hyerr.hbuiltin.cといった、通常はBison/Yaccなどのツールによって生成されるファイルを、ソースリポジトリに直接チェックインするように変更しています。これにより、Bison/YaccがインストールされていないシステムでもGoコンパイラをビルドできるようになり、ビルド環境の依存関係が緩和されます。

コミット

commit d53cdd177565ef349e547b7125d2c1e2094d62c2
Author: Russ Cox <rsc@golang.org>
Date:   Fri Feb 3 10:53:31 2012 -0500

    gc: check in y.tab.[ch], yerr.h, builtin.c.
    
    This enables builds on systems without Bison/yacc.
    
    R=golang-dev, iant
    CC=golang-dev
    https://golang.org/cl/5622051

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/d53cdd177565ef349e547b7125d2c1e2094d62c2

元コミット内容

Goコンパイラ(gc)において、y.tab.cy.tab.hyerr.hbuiltin.cの各ファイルをリポジトリにチェックインする。これにより、Bison/Yaccがインストールされていないシステムでもビルドが可能になる。

変更の背景

Goコンパイラは、そのパーサーの生成にBison(Yacc互換ツール)を使用しています。これまでのビルドプロセスでは、go.yのような文法定義ファイルからy.tab.cy.tab.hといったC言語のソースコードがビルド時に生成されていました。しかし、この方式では、Goコンパイラをビルドする全ての環境にBison/Yaccがインストールされている必要がありました。

これは、特にクロスコンパイル環境や、開発者がGoのソースコードからコンパイラをビルドする際に、追加の依存関係を管理する必要があるという課題を抱えていました。Bison/Yaccのインストールは、システムによっては複雑であったり、特定のバージョンが必要であったりする場合があります。

このコミットの目的は、このような外部ツールの依存関係を解消し、Goコンパイラのビルドをより簡単かつポータブルにすることです。生成されたファイルを直接リポジトリに含めることで、ビルド時にこれらのツールを必要とせず、Goのソースコードと標準的なCコンパイラがあればビルドが完結するようになります。

前提知識の解説

1. コンパイラのフロントエンドとパーサー

コンパイラは、ソースコードを機械が実行できる形式に変換するソフトウェアです。その過程は大きく分けて「フロントエンド」と「バックエンド」に分かれます。

  • フロントエンド: ソースコードを解析し、抽象構文木(AST: Abstract Syntax Tree)などの中間表現を生成します。これには「字句解析(Lexical Analysis)」と「構文解析(Syntax Analysis)」が含まれます。
  • バックエンド: 中間表現を最適化し、ターゲットマシン向けの機械語コードを生成します。

このコミットが関連するのは、フロントエンドの「構文解析」部分です。

2. 字句解析と構文解析

  • 字句解析(Lexical Analysis): ソースコードを読み込み、意味のある最小単位である「トークン(token)」の並びに分解します。この処理を行うプログラムを「字句解析器(lexer)」または「スキャナー(scanner)」と呼びます。
  • 構文解析(Syntax Analysis): 字句解析器が生成したトークンの並びが、プログラミング言語の文法規則に則っているかを検証し、通常は抽象構文木を構築します。この処理を行うプログラムを「構文解析器(parser)」と呼びます。

3. Yacc/Bison

  • Yacc (Yet Another Compiler Compiler): Unix系システムで広く使われているパーサー生成器です。文法規則を記述したファイル(通常は.y拡張子)を入力として受け取り、C言語の構文解析器のソースコード(y.tab.cy.tab.hなど)を生成します。
  • Bison: GNUプロジェクトによるYaccのフリーソフトウェア実装です。Yaccとほぼ互換性があり、より多くの機能や改善が加えられています。GoコンパイラではBisonが使用されていました。

Yacc/Bisonは、LALR(1)パーサーと呼ばれる種類のパーサーを生成します。これは、効率的で強力な構文解析器を自動生成するためのツールとして、多くのプログラミング言語のコンパイラやインタプリタで利用されています。

4. y.tab.c, y.tab.h, yerr.h, builtin.c

  • y.tab.c: Bison/Yaccによって生成されるC言語のソースファイルで、構文解析器のロジックが実装されています。
  • y.tab.h: Bison/Yaccによって生成されるC言語のヘッダーファイルで、トークン定義やパーサーのインターフェースなどが含まれます。
  • yerr.h: Bisonの出力の一部として、エラーメッセージや関連する定義が含まれるヘッダーファイルです。
  • builtin.c: Goコンパイラ内部で、Go言語の組み込み関数や型に関する情報が定義されているC言語のファイルです。このファイルも、特定のツール(mkbuiltinスクリプト)によって生成されることがあります。

これらのファイルは、Goコンパイラのビルドにおいて、Go言語のソースコードを解析し、内部表現に変換するために不可欠なコンポーネントです。

技術的詳細

このコミットの技術的な核心は、GoコンパイラのビルドシステムからBison/Yaccへの実行時依存を排除することにあります。

  1. 生成ファイルの直接チェックイン:

    • 以前は、src/cmd/gc/go.yというGo言語の文法定義ファイルから、ビルド時にBisonを使ってsrc/cmd/gc/y.tab.csrc/cmd/gc/y.tab.hが生成されていました。
    • 同様に、src/cmd/gc/yerr.hもBisonの出力から生成され、src/cmd/gc/builtin.cmkbuiltinスクリプトによって生成されていました。
    • このコミットでは、これらの生成されるファイルをGitリポジトリに直接追加(チェックイン)しています。これにより、Goコンパイラをビルドする際に、BisonやYacc、あるいはmkbuiltinスクリプトを実際に実行する必要がなくなります。
  2. ビルドスクリプトの変更:

    • src/Make.clibsrc/cmd/gc/Makefileが変更され、y.tab.[ch]yerr.hbuiltin.cCLEANFILES(クリーンアップ時に削除されるファイル)から削除されています。これは、これらのファイルがもはやビルド時に生成される一時ファイルではなく、リポジトリに永続的に存在するファイルであることを示しています。
    • src/cmd/gc/Makefileでは、y.tab.hyerr.hの生成ルールが残されていますが、これは主に開発者が文法定義(go.y)を変更した場合に手動でこれらのファイルを更新するためのものです。通常のビルドでは、チェックインされたファイルが使用されます。
    • src/cmd/gc/mkbuiltinスクリプトも変更され、builtin.cの扱いが、生成後に比較して必要であれば更新するというロジックに変更されています。これは、builtin.cがチェックインされたファイルであることを前提とした変更です。
    • src/cmd/gc/mkbuiltin1.cには// +build ignoreディレクティブが追加されました。これはGoのビルドシステムに対して、このファイルを通常のビルドプロセスから除外するよう指示するものです。このファイルは、mkbuiltinスクリプトによってのみ使用されるユーティリティであり、Goのツールチェーンが直接コンパイルする必要がないためです。
  3. .hgignoreの変更:

    • Mercurial(GoプロジェクトがGitに移行する前に使用していたバージョン管理システム)の無視リストである.hgignoreから、y.tab.[ch]builtin.cyerr.hが削除されています。これは、これらのファイルが無視されるべき生成物ではなく、バージョン管理下に置かれるべきソースファイルの一部として扱われるようになったことを意味します。

この変更により、Goコンパイラのビルドは、Goのソースコードと標準的なCコンパイラ(Goコンパイラ自体がCで書かれた部分を含むため)があれば完結するようになり、ビルド環境のセットアップが大幅に簡素化されます。これは、特に新しい環境でのGoコンパイラのビルドや、Goのブートストラップ(Goコンパイラ自身をGoで書かれたコードでビルドするプロセス)において、非常に重要な改善となります。

コアとなるコードの変更箇所

このコミットのコアとなる変更は、主に以下のファイルに集中しています。

  1. src/cmd/gc/y.tab.c: Bisonによって生成されたGo言語の構文解析器のC言語ソースコードが新規追加されています。このファイルは非常に大きく、コミットの大部分を占めています。
  2. src/cmd/gc/y.tab.h: y.tab.cに対応するヘッダーファイルで、トークン定義などが含まれます。これも新規追加です。
  3. src/cmd/gc/yerr.h: Bisonのエラー定義を含むヘッダーファイルで、新規追加です。
  4. src/cmd/gc/builtin.c: 組み込み関数や型の定義を含むC言語ファイルで、以前はbuiltin.c.bootという名前で存在し、ビルド時にbuiltin.cにコピーされていました。このコミットでbuiltin.cが直接チェックインされるようになりました。
  5. .hgignore: y.tab.[ch], builtin.c, yerr.hが無視リストから削除され、これらのファイルがバージョン管理されるようになりました。
  6. src/Make.clib および src/cmd/gc/Makefile: ビルドスクリプトが変更され、これらのファイルが生成物として扱われなくなり、クリーンアップの対象からも外されました。また、y.tab.hyerr.hの生成ルールは残されていますが、これは手動更新用であり、通常のビルドでは使用されません。
  7. src/cmd/gc/mkbuiltin: builtin.cの生成ロジックが、チェックインされたファイルとの比較と更新を行うように変更されました。
  8. src/cmd/gc/mkbuiltin1.c: // +build ignoreディレクティブが追加され、Goツールチェーンによる通常のビルドから除外されるようになりました。

コアとなるコードの解説

このコミットの核心は、Goコンパイラのビルドプロセスにおける「ブートストラップ」の問題を解決することにあります。

Goコンパイラは、Go言語自体で書かれていますが、その初期バージョンや、Go言語の新しいバージョンをビルドするためには、既存のコンパイラが必要です。この「鶏が先か、卵が先か」という問題は、コンパイラ開発におけるブートストラップ問題として知られています。

Goコンパイラの初期段階では、C言語で書かれた部分(特にパーサー)が存在しました。このパーサーはBison/Yaccによって生成されるCコードに依存していました。つまり、Goコンパイラをビルドするためには、まずBison/Yaccがシステムにインストールされている必要があったのです。

このコミットは、Bison/Yaccによって生成されるy.tab.cy.tab.hyerr.hといったファイルを、Goのソースコードリポジトリに直接含めることで、この外部依存を解消しました。これにより、Goコンパイラのビルドは、Goのソースコードと標準的なCコンパイラがあれば完結するようになります。

具体的には、以下の点が重要です。

  • y.tab.cy.tab.hの役割: これらはGo言語の文法をC言語で実装したもので、Goのソースコードを解析して抽象構文木を構築する役割を担います。これらがリポジトリに存在することで、ビルド時にBisonを実行してこれらを生成する必要がなくなります。
  • yerr.hの役割: パーサーが構文エラーを検出した際に使用するエラーメッセージや関連する定義が含まれます。これも同様に、ビルド時の生成が不要になります。
  • builtin.cの役割: Go言語の組み込み関数や型(例: len, cap, int, stringなど)に関する情報がC言語で定義されています。このファイルも、以前はmkbuiltinスクリプトによって生成されていましたが、このコミットで直接チェックインされるようになりました。mkbuiltinスクリプトは、builtin.cが最新の状態であることを確認し、必要に応じて更新するためのツールとして残ります。
  • ビルドシステムの簡素化: Makefilemkbuiltinスクリプトの変更は、これらのファイルがもはや「生成物」ではなく「ソースコードの一部」として扱われるようになったことを反映しています。これにより、ビルドプロセスがより予測可能になり、外部ツールの有無に左右されなくなります。

この変更は、Goコンパイラのビルドの信頼性とポータビリティを大幅に向上させ、Go言語の普及に貢献しました。開発者は、Bison/Yaccのインストールやバージョン管理について心配することなく、Goコンパイラを簡単にビルドできるようになりました。

関連リンク

参考にした情報源リンク

  • コミットメッセージと差分情報 (./commit_data/11591.txt)
  • Go言語の公式ドキュメントおよびソースコードの構造に関する一般的な知識
  • コンパイラ理論(字句解析、構文解析、パーサー生成器)に関する一般的な知識
  • Bison/Yaccの機能と用途に関する一般的な知識
  • Goプロジェクトのビルドシステムに関する一般的な知識
  • Mercurialの.hgignoreファイルの動作に関する一般的な知識