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

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

このコミットは、Go言語のツールチェインにおけるアセンブラ(5a, 6a, 8a)およびCコンパイラ(cc)のビルドプロセスを改善することを目的としています。具体的には、これらのツールが依存するy.tab.cy.tab.hというBison/Yaccによって生成されるファイルをリポジトリに直接チェックインすることで、Bison/YaccがインストールされていないシステムでもGoツールチェインのビルドが可能になります。これにより、ビルド環境の依存関係が緩和され、より多くの環境でのGoの利用が促進されます。

コミット

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

    5a, 6a, 8a, cc: check in y.tab.[ch]
    
    This enables builds on systems without Bison/yacc.
    
    R=golang-dev, bradfitz
    CC=golang-dev
    https://golang.org/cl/5622050

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

https://github.com/golang/go/commit/0f78ee574b230d72fd8112bce9a94b6cf107ccdd

元コミット内容

このコミットは、Go言語のアセンブラ(5a, 6a, 8a)とCコンパイラ(cc)に関連するy.tab.cおよびy.tab.hファイルをバージョン管理システムにチェックインするものです。これにより、Bison/YaccがインストールされていないシステムでもGoツールチェインのビルドが可能になることが意図されています。

変更の背景

Go言語の初期のビルドプロセスでは、アセンブラやCコンパイラの一部がBison(またはYacc)というパーサジェネレータに依存していました。Bisonは、文法定義ファイル(通常.yまたは.yy拡張子を持つ)からC言語のソースコード(y.tab.cy.tab.h)を生成するツールです。これらの生成されたファイルは、プログラムの構文解析(パース)を行うためのロジックを含んでいます。

しかし、Goツールチェインをビルドする際に、開発者のシステムにBison/Yaccがインストールされていることを前提とすることは、ビルド環境のセットアップを複雑にし、特にBison/Yaccが標準で提供されていない、あるいはバージョン管理が難しいシステムでは、ビルドの障壁となっていました。

このコミットの背景には、Goのビルドプロセスをよりポータブルで、依存関係の少ないものにするという明確な意図があります。y.tab.cy.tab.hをリポジトリに直接含めることで、ビルド時にBison/Yaccを動的に実行する必要がなくなり、結果として、Bison/Yaccがインストールされていない環境でもGoツールチェインをビルドできるようになります。これは、Goの普及とアクセシビリティを高める上で重要なステップでした。

前提知識の解説

1. コンパイラとアセンブラの役割

  • コンパイラ: 人間が書いた高水準言語(例: Go, C)のソースコードを、コンピュータが直接実行できる機械語や中間コードに変換するプログラムです。この変換プロセスには、字句解析、構文解析、意味解析、最適化、コード生成などの段階があります。
  • アセンブラ: アセンブリ言語(機械語と1対1に対応する低水準言語)で書かれたコードを、実際の機械語に変換するプログラムです。アセンブリ言語は、特定のCPUアーキテクチャに特化しており、ハードウェアを直接制御する際に用いられます。

2. 字句解析と構文解析

コンパイラやアセンブラがソースコードを処理する際の初期段階です。

  • 字句解析(Lexical Analysis): ソースコードを、意味を持つ最小単位である「トークン(token)」の並びに分解するプロセスです。例えば、int x = 10;というコードは、int(キーワード)、x(識別子)、=(演算子)、10(整数リテラル)、;(区切り文字)といったトークンに分解されます。この処理を行うプログラムを「字句解析器(lexer)」または「スキャナ(scanner)」と呼びます。
  • 構文解析(Syntax Analysis): 字句解析器によって生成されたトークンの並びが、その言語の文法規則に合致しているかを確認し、通常は抽象構文木(Abstract Syntax Tree: AST)と呼ばれるツリー構造を構築するプロセスです。この処理を行うプログラムを「構文解析器(parser)」と呼びます。

3. Yacc/Bison (パーサジェネレータ)

  • Yacc (Yet Another Compiler Compiler): Unix系システムで広く使われていたパーサジェネレータです。文法規則を記述したファイル(通常.y拡張子)を入力として受け取り、C言語で書かれた構文解析器のソースコード(y.tab.cy.tab.h)を生成します。
  • Bison: GNUプロジェクトによるYaccのフリーソフトウェア実装であり、Yaccとほぼ互換性があります。現代の多くのシステムではYaccの代わりにBisonが使われています。Bisonも同様に、文法定義からC/C++などの言語で書かれたパーサを生成します。

これらのツールは、複雑な文法を持つプログラミング言語のパーサを手書きする手間を大幅に削減し、文法変更への対応を容易にします。生成されるy.tab.cファイルには、構文解析のロジック(状態遷移テーブルやアクションコードなど)がC言語で記述されており、y.tab.hにはトークン定義などが含まれます。

技術的詳細

このコミットの技術的詳細は、主にBison/Yaccによって生成されるファイルをGoのソースリポジトリに直接含めること、そしてそれに関連するビルドスクリプトの変更に集約されます。

  1. y.tab.cy.tab.hのチェックイン:

    • src/cmd/5a/, src/cmd/6a/, src/cmd/8a/ はそれぞれ、Plan 9アセンブラの5A (ARM), 6A (x86), 8A (amd64) に対応します。
    • src/cmd/cc/ は、Plan 9 Cコンパイラに対応します。
    • これらのディレクトリに、Bison 2.4.1によって生成されたと明記されているy.tab.cy.tab.hファイルが追加されています。これらのファイルは、各アセンブラやコンパイラの構文解析部分を担っています。
    • 通常、これらのファイルはビルド時に自動生成されるため、バージョン管理システムには含めないのが一般的です(生成されたファイルはリポジトリを肥大化させ、手動での変更が困難になるため)。しかし、このコミットでは「Bison/Yaccがないシステムでのビルドを可能にする」という明確な目的のために、あえてチェックインされています。
  2. src/Make.ctoolの変更:

    • src/Make.ctoolは、GoツールチェインのC言語部分のビルドを制御するMakefileの一部です。
    • 変更前: CLEANFILES+=y.tab.[ch] という行がありました。これは、make cleanコマンドが実行された際に、y.tab.cy.tab.hファイルを削除する設定です。これは、これらのファイルが生成物であり、クリーンアップの対象であることを示しています。
    • 変更後: この行が削除されています。これは、y.tab.cy.tab.hがもはや生成物ではなく、リポジトリの一部として扱われるようになったことを意味します。これにより、make cleanを実行してもこれらのファイルが削除されなくなり、ビルド時にBison/Yaccを再実行する必要がなくなります。

この変更は、ビルドシステムの依存関係を減らすという点で大きなメリットがありますが、一方で、パーサの文法定義(.yファイル)が変更された場合、手動でBisonを実行してy.tab.c/y.tab.hを再生成し、その変更をコミットする必要が生じるというデメリットもあります。これは、生成されたコードと元の文法定義との同期を保つための追加の管理オーバーヘッドを意味します。しかし、Goのツールチェインの安定性を考慮すると、このトレードオフは許容範囲と判断されたと考えられます。

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

このコミットにおけるコアとなるコードの変更は、以下のファイルに対する追加と削除です。

  • src/Make.ctool:

    --- a/src/Make.ctool
    +++ b/src/Make.ctool
    @@ -15,8 +15,6 @@ $(TARG): $(OFILES) $(LIB)
     
     $(OFILES): $(HFILES)
     
    -CLEANFILES+=y.tab.[ch]
    -
     clean:
     	rm -f *.$(HOST_O) $(TARG) $(CLEANFILES)
    
    • CLEANFILES+=y.tab.[ch] の行が削除されました。
  • src/cmd/5a/y.tab.c: 新規追加 (2949行の挿入)

  • src/cmd/5a/y.tab.h: 新規追加 (166行の挿入)

  • src/cmd/6a/y.tab.c: 新規追加 (2730行の挿入)

  • src/cmd/6a/y.tab.h: 新規追加 (135行の挿入)

  • src/cmd/8a/y.tab.c: 新規追加 (2852行の挿入)

  • src/cmd/8a/y.tab.h: 新規追加 (135行の挿入)

  • src/cmd/cc/y.tab.c: 新規追加 (3811行の挿入)

  • src/cmd/cc/y.tab.h: 新規追加 (228行の挿入)

これらのy.tab.cy.tab.hファイルは、Bisonによって生成されたC言語のソースコードであり、各ツールの構文解析器の実装を含んでいます。

コアとなるコードの解説

src/Make.ctoolの変更

CLEANFILES+=y.tab.[ch]の削除は、ビルドシステムにおけるy.tab.cy.tab.hの扱いを根本的に変更するものです。

  • 変更前: CLEANFILES変数にy.tab.[ch]が追加されていたため、make cleanコマンドを実行すると、これらのファイルが削除されていました。これは、これらのファイルがビルドプロセス中に生成される一時的なファイル、または派生ファイルであることを示唆しています。つまり、ビルドのたびにBison/Yaccが実行され、これらのファイルが再生成されることを前提としていました。
  • 変更後: この行が削除されたことで、y.tab.cy.tab.hはもはやクリーンアップの対象ではなくなりました。これは、これらのファイルがソースコードの一部として扱われ、リポジトリに永続的に存在することを意味します。これにより、ビルド時にBison/Yaccがシステムにインストールされている必要がなくなり、ビルド環境の依存関係が軽減されます。

y.tab.cy.tab.hの新規追加

cmdディレクトリ(5a, 6a, 8a, cc)へのy.tab.cy.tab.hの追加は、Goツールチェインのビルドプロセスにおける外部ツール(Bison/Yacc)への依存を排除するための直接的な手段です。

  • y.tab.c: このファイルは、Bisonによって生成されたC言語のソースコードで、構文解析器のロジック(状態機械、アクション関数など)を含んでいます。このファイルがリポジトリに存在することで、ビルドシステムはBisonを呼び出すことなく、直接このCファイルをコンパイルしてパーサを生成できます。
  • y.tab.h: このヘッダファイルには、トークン定義(#define定数)や、パーサが使用するデータ構造(YYSTYPEなど)の宣言が含まれています。これもまた、Bisonの実行なしにコンパイルを可能にするために必要です。

この変更により、Goツールチェインのビルドは、Bison/Yaccがインストールされていない環境でも「箱から出してすぐに(out-of-the-box)」動作するようになります。これは、Goのクロスコンパイルや、様々なOS・ディストリビューションでのビルドの容易性を向上させる上で非常に重要です。一方で、パーサの文法定義(.yファイル)が変更された場合には、開発者が手動でBisonを実行し、生成されたy.tab.c/y.tab.hを更新してコミットする必要があるという、新たな運用上の考慮事項が生じます。

関連リンク

参考にした情報源リンク