[インデックス 11123] ファイルの概要
このコミットは、Go言語のパーサジェネレータであるgoyacc
のサンプルコードunits.y
におけるビルドエラーを修正するものです。このエラーは、Go標準ライブラリのAPI変更(utf8
パッケージの移動、strconv.Atof64
の削除、文字型がint
からrune
への変更など)によって引き起こされました。また、goyacc
の利用方法に関するコメントも修正されています。
コミット
commit 26ba35666ec72b0969156c5f2d3f8339c188a7ec
Author: Shenghou Ma <minux.ma@gmail.com>
Date: Thu Jan 12 07:54:20 2012 -0800
goyacc: fix units.y build breakage
This breakage is mainly due to API changes in pkg.
(e.g., package utf8 moved to unicode/utf8;
remove of strconv.Atof64;
change character type from int to rune.)
Also correct the usage comment.
This fixes issue 2646.
PS: I don't change the goyacc.go, because I think token type
should not be force to rune.
R=golang-dev, adg, rogpeppe, r, r
CC=golang-dev
https://golang.org/cl/5502093
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/26ba35666ec72b0969156c5f2d3f8339c188a7ec
元コミット内容
goyacc: fix units.y build breakage
This breakage is mainly due to API changes in pkg.
(e.g., package utf8 moved to unicode/utf8;
remove of strconv.Atof64;
change character type from int to rune.)
Also correct the usage comment.
This fixes issue 2646.
PS: I don't change the goyacc.go, because I think token type
should not be force to rune.
R=golang-dev, adg, rogpeppe, r, r
CC=golang-dev
https://golang.org/cl/5502093
変更の背景
このコミットの主な背景は、Go言語の標準ライブラリにおけるAPIの変更です。Go言語は当時まだ開発の初期段階にあり、言語の安定化と改善のためにAPIの変更が頻繁に行われていました。goyacc
のunits.y
サンプルコードは、これらの変更に追従できておらず、ビルドが失敗する状態になっていました。具体的には、以下の主要な変更が影響していました。
utf8
パッケージの移動:utf8
パッケージがunicode/utf8
という新しいパスに移動しました。strconv.Atof64
の削除: 浮動小数点数文字列をパースするためのstrconv.Atof64
関数が削除され、より汎用的な関数に置き換えられました。- 文字型の変更: 文字を表す型が
int
からrune
に移行しました。これはGo言語がUnicodeをより適切に扱うための重要な変更でした。
これらのAPI変更により、units.y
は古いAPIを参照しているためコンパイルエラーが発生していました。このコミットは、これらの変更に対応し、units.y
が再びビルドできるようにすることを目的としています。コミットメッセージに「This fixes issue 2646」とあることから、これは既知の不具合として追跡されていたことがわかります。
前提知識の解説
このコミットを理解するためには、以下のGo言語に関する前提知識が役立ちます。
- Go言語の進化とAPI変更: Go言語は2009年に公開され、2012年時点ではまだバージョン1.0がリリースされたばかりの比較的新しい言語でした。そのため、言語仕様や標準ライブラリのAPIが頻繁に変更される時期でした。これは、言語設計の改善や安定化のために必要なプロセスです。
goyacc
:goyacc
は、Go言語で書かれたYacc(Yet Another Compiler Compiler)互換のパーサジェネレータです。Yaccは、文法定義から構文解析器(パーサ)のソースコードを自動生成するツールであり、コンパイラやインタプリタの作成によく用いられます。units.y
はgoyacc
の機能を示すためのサンプル文法ファイルです。rune
型: Go言語において、rune
型はUnicodeのコードポイント(文字)を表す組み込み型です。これはint32
のエイリアスであり、UTF-8でエンコードされた文字列から個々のUnicode文字を扱う際に使用されます。Go言語の初期には、文字をint
型で扱うことがありましたが、Unicodeの複雑さを適切に扱うためにrune
型が導入されました。utf8
パッケージとunicode/utf8
パッケージ:utf8
パッケージは、UTF-8エンコーディングされたテキストを扱うためのユーティリティ関数を提供します。Goの標準ライブラリの整理の一環として、このパッケージはunicode
パッケージの下に移動され、unicode/utf8
という新しいインポートパスになりました。strconv
パッケージ:strconv
パッケージは、基本的なデータ型(文字列、整数、浮動小数点数、真偽値など)と文字列との間の変換機能を提供します。初期のGoではAtof64
のような特定の型に特化した関数がありましたが、後にParseFloat
のようなより汎用的な関数に統合されました。
技術的詳細
このコミットは、src/cmd/goyacc/units.y
ファイルに対して、Go標準ライブラリのAPI変更に合わせた複数の修正を適用しています。
-
インポートパスの変更:
utf8
パッケージのインポートパスが"utf8"
から"unicode/utf8"
に変更されました。これは、パッケージの再編成による直接的な影響です。
-
文字型の
int
からrune
への移行:peekrune
変数の型がint
からrune
に変更されました。UnitsLex
型のLex
メソッド内のローカル変数c
の型がint
からrune
に変更されました。ralpha
関数とrdigit
関数の引数c
の型がint
からrune
に変更されました。getrune
関数の戻り値の型がint
からrune
に変更され、ローカル変数c
の型もint
からrune
に変更されました。Lex
メソッドの戻り値はトークン型を表すint
であるため、rune
型のc
を返す際にはint(c)
と明示的な型変換が追加されました。これにより、Unicodeコードポイントをint
として返すという既存のインターフェースが維持されます。
-
strconv.Atof64
からstrconv.ParseFloat
への変更:strconv.Atof64(sym)
の呼び出しがstrconv.ParseFloat(sym, 64)
に変更されました。ParseFloat
は、文字列を浮動小数点数に変換するより汎用的な関数であり、第2引数でビットサイズ(float64
の場合は64
)を指定する必要があります。
-
goyacc
使用方法コメントの修正:units.y
の冒頭にあるgoyacc
の利用方法に関するコメントが、goyacc units.y
からgoyacc -p "units_" units.y
に修正されました。これは、goyacc
が生成するコードのパッケージ名を指定する-p
オプションの一般的な使用法を反映しています。
これらの変更は、units.y
がGo言語の進化するAPIと互換性を保ち、正しくビルドおよび実行されるようにするために不可欠でした。
コアとなるコードの変更箇所
src/cmd/goyacc/units.y
ファイルにおける主要な変更点は以下の通りです。
--- a/src/cmd/goyacc/units.y
+++ b/src/cmd/goyacc/units.y
@@ -14,7 +14,7 @@
// units.y
// example of a goyacc program
// usage is
-// goyacc units.y (produces y.go)
+// goyacc -p "units_" units.y (produces y.go)
// 6g y.go
// 6l y.6
// ./6.out $GOROOT/src/cmd/goyacc/units
@@ -33,7 +33,7 @@ import (
"os"
"math"
"strconv"
- "utf8"
+ "unicode/utf8"
)
const (
@@ -58,7 +58,7 @@ var lineno int // current input line number
var linep int // index to next rune in unput
var nerrors int // error count
var one Node // constant one
-var peekrune int // backup runt from input
+var peekrune rune // backup runt from input
var retnode1 Node
var retnode2 Node
var retnode Node
@@ -212,7 +212,8 @@ expr0:
type UnitsLex int
func (UnitsLex) Lex(yylval *units_SymType) int {
- var c, i int
+ var c rune
+ var i int
c = peekrune
peekrune = ' '
@@ -242,7 +243,7 @@ loop:
yylval.numb = 3
return SUP
}
- return c
+ return int(c)
alpha:
sym = ""
@@ -267,7 +268,7 @@ numb:
}
}
peekrune = c
- f, err := strconv.Atof64(sym)
+ f, err := strconv.ParseFloat(sym, 64)
if err != nil {
fmt.Printf("error converting %v\n", sym)
f = 0
@@ -362,7 +363,7 @@ func main() {
* all characters that have some
* meaning. rest are usable as names
*/
-func ralpha(c int) bool {
+func ralpha(c rune) bool {
switch c {
case 0, '+', '-', '*', '/', '[', ']', '(', ')',
'^', ':', '?', ' ', '\t', '.', '|', '#',
@@ -375,7 +376,7 @@ func ralpha(c int) bool {
/*
* number forming character
*/
-func rdigit(c int) bool {
+func rdigit(c rune) bool {
switch c {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'.', 'e', '+', '-':
@@ -577,8 +578,9 @@ func readline() bool {
return false
}
-func getrune() int {
- var c, n int
+func getrune() rune {
+ var c rune
+ var n int
if linep >= len(line) {
return 0
コアとなるコードの解説
-
goyacc
使用方法コメントの更新:-// goyacc units.y (produces y.go) +// goyacc -p "units_" units.y (produces y.go)
この変更は、
goyacc
のコマンドライン引数の推奨される使用法を反映しています。-p
オプションは、生成されるGoコードのパッケージ名を指定するために使用され、これにより生成されたパーサが特定のパッケージに属するように設定できます。 -
utf8
パッケージのインポートパス変更:- "utf8" + "unicode/utf8"
これは、Go標準ライブラリ内で
utf8
パッケージがunicode
パッケージのサブディレクトリに移動したことによる直接的な修正です。これにより、units.y
は正しいパスからutf8
関連の関数をインポートできるようになります。 -
int
からrune
への型変更:-var peekrune int // backup runt from input +var peekrune rune // backup runt from input
- var c, i int + var c rune + var i int
-func ralpha(c int) bool { +func ralpha(c rune) bool {
-func rdigit(c int) bool { +func rdigit(c rune) bool {
-func getrune() int { - var c, n int +func getrune() rune { + var c rune + var n int
これらの変更は、Go言語が文字を表現するために
int
からrune
型に移行したことに対応しています。peekrune
、Lex
メソッド内のc
、ralpha
、rdigit
、getrune
関数内のc
など、文字を扱う変数の型がrune
に変更されました。これにより、Unicode文字が正しく扱われるようになります。 -
Lex
メソッドの戻り値の型変換:- return c + return int(c)
Lex
メソッドは、Yaccの仕様によりトークン型を表すint
を返す必要があります。しかし、文字c
の型がrune
に変更されたため、int(c)
と明示的に型変換を行うことで、Lex
メソッドのインターフェースを維持しつつ、内部でrune
型を扱うことができるようになります。 -
strconv.Atof64
からstrconv.ParseFloat
への変更:- f, err := strconv.Atof64(sym) + f, err := strconv.ParseFloat(sym, 64)
strconv
パッケージのAPI変更に対応しています。Atof64
は削除され、より汎用的なParseFloat
関数が導入されました。ParseFloat
は、パースする浮動小数点数のビットサイズを第2引数で指定する必要があり、ここではfloat64
を表す64
が渡されています。
これらの変更により、units.y
はGo言語の最新のAPIに準拠し、ビルドエラーが解消されました。
関連リンク
- Go Issue 2646: https://code.google.com/p/go/issues/detail?id=2646 (このコミットが修正した問題のトラッキング)
- Go Change-List 5502093: https://golang.org/cl/5502093 (このコミットの元のコードレビュー)
参考にした情報源リンク
- なし (提供された情報とコミット内容のみで解説を生成しました)