[インデックス 1787] ファイルの概要
このコミットは、Go言語のscanner
パッケージにおけるドキュメンテーションの改善を目的としています。具体的には、scanner.go
ファイル内のコメントが更新され、パッケージの利用方法やScanner
構造体、Init
関数、Scan
関数の役割がより明確に記述されています。
コミット
commit 2aa77352fcdc0cc67612d682f9e16437fb423d76
Author: Robert Griesemer <gri@golang.org>
Date: Mon Mar 9 17:16:42 2009 -0700
scanner.go documentation
R=r
DELTA=22 (8 added, 3 deleted, 11 changed)
OCL=25947
CL=25955
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/2aa77352fcdc0cc67612d682f9e16437fb423d76
元コミット内容
scanner.go documentation
R=r
DELTA=22 (8 added, 3 deleted, 11 changed)
OCL=25947
CL=25955
変更の背景
このコミットは2009年3月に行われており、Go言語がまだ一般に公開される前の初期開発段階に当たります。Go言語は2009年11月に初めて公開されました。この時期は、言語の基本的なツールチェインや標準ライブラリが活発に構築・洗練されていた段階です。
scanner
パッケージは、Go言語のソースコードを字句解析(トークン化)するための基本的なコンポーネントであり、コンパイラやその他のツールにとって不可欠な部分です。初期の段階では、機能の実装が優先され、ドキュメンテーションは後回しにされることがよくあります。しかし、コードベースが成長し、より多くの開発者が関わるようになるにつれて、コードの理解を深め、利用を促進するための明確で包括的なドキュメンテーションの重要性が増します。
このコミットの背景には、scanner
パッケージの内部構造と利用方法を、将来の利用者や開発者に対してより分かりやすく説明するという意図があったと考えられます。特に、Scanner
構造体の初期化方法やScan
関数の振る舞いに関する説明を充実させることで、パッケージの使いやすさを向上させることが目的だったでしょう。
前提知識の解説
字句解析(Lexical Analysis / Tokenization)
字句解析とは、プログラミング言語のソースコードを、意味を持つ最小単位である「トークン」の並びに分解するプロセスのことです。例えば、x = 10 + y;
というコードは、x
(識別子)、=
(代入演算子)、10
(整数リテラル)、+
(加算演算子)、y
(識別子)、;
(セミコロン)といったトークンに分解されます。このプロセスは、コンパイラやインタプリタがソースコードを理解し、次の段階である構文解析(Parsing)に進むための前処理として非常に重要です。
スキャナー(Scanner / Lexer / Tokenizer)
字句解析を行うプログラムやモジュールをスキャナー、レキサー、またはトークナイザーと呼びます。Go言語のscanner
パッケージは、この役割を担います。ソースコードのバイト列を入力として受け取り、それをトークンに変換して出力します。
Go言語のパッケージとドキュメンテーション
Go言語では、コードは「パッケージ」という単位で組織されます。各パッケージは、関連する機能の集合体であり、再利用可能なモジュールとして機能します。Goの標準的なドキュメンテーションツールであるgo doc
は、ソースコード内のコメント(特にエクスポートされた識別子の直前のコメント)を解析してドキュメントを生成します。そのため、Go言語では、コード内に適切なコメントを記述することが、そのまま公式ドキュメントとなるため非常に重要視されています。
ErrorHandler
インターフェース
このコミットで言及されているErrorHandler
は、スキャナーが字句解析中にエラー(例えば、不正な文字シーケンス)を検出した場合に、そのエラーをどのように処理するかを定義するためのインターフェースです。これにより、スキャナーの利用者(例えば、コンパイラ)は、独自のエラー処理ロジックを実装して、エラーメッセージの表示方法やエラーからの回復方法をカスタマイズできます。
技術的詳細
このコミットの技術的な詳細は、主にscanner.go
ファイル内のコメントの変更に集約されます。
-
パッケージコメントの移動と追加:
- 元のコードでは
package scanner
の直後にパッケージ全体の説明が書かれていましたが、これがimport
文の後に移動し、さらに//\n+package scanner
という行が追加されています。これは、Goのドキュメンテーションツールがパッケージコメントを正しく認識するための慣習に合わせたものと考えられます。 - パッケージコメントの例示コード(
main
関数を含む)がより明確になり、Scan()
関数の戻り値の利用方法が示されています。
- 元のコードでは
-
ErrorHandler
インターフェースのコメント改善:ErrorHandler
インターフェースの定義前に、その役割(構文エラーが発生した場合にError()
が呼び出されること)がより詳細に説明されています。
-
Scanner
構造体のコメント追加:Scanner
構造体の定義前に、Scanner
が「与えられたテキストを処理する間のスキャナーの内部状態を保持する」こと、そして「使用前にInit()
を介して初期化されなければならない」ことが明記されました。- さらに、「パッケージコメントのサンプル使用例も参照」という指示が追加され、ドキュメント間の連携が図られています。
-
Init
関数のコメント改善:Init
関数のコメントが大幅に書き直されています。- 変更前は「スキャナーを初期化する」という一般的な説明でしたが、変更後は「
Init()
はスキャナーSをテキストsrc
をトークン化するために準備する」と具体化されています。 err
(エラーハンドラ)とscan_comments
(コメントをトークンとして認識するかどうか)の引数の役割がより詳細に説明されています。特にscan_comments
がfalse
の場合に、改行文字とコメントが空白として扱われ無視される点が明確にされました。
-
Scan
関数のコメント改善:Scan
関数のコメントも書き直されています。- 変更前は「次のトークンをスキャンする」という説明でしたが、変更後は「
Scan()
は次のトークンをスキャンし、ソース内のトークンのバイト位置、そのトークン値、そしてトークンが識別子、基本型リテラル、またはコメントである場合の対応するリテラルテキストを返す」と、戻り値の詳細が追加されました。特に、コメントもリテラルテキストとして返される可能性がある点が追記されています。
これらの変更は、コードの機能自体には影響を与えませんが、Go言語のドキュメンテーションのベストプラクティスに沿って、パッケージの利用者がより簡単にscanner
パッケージを理解し、正しく使用できるようにするための重要な改善です。
コアとなるコードの変更箇所
src/lib/go/scanner.go
ファイルの変更がコアとなります。
--- a/src/lib/go/scanner.go
+++ b/src/lib/go/scanner.go
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package scanner
-
// A Go scanner. Takes a []byte as source which can then be
// tokenized through repeated calls to the Scan() function.
//
@@ -23,6 +21,8 @@ package scanner
// println(pos, token.TokenString(tok), string(lit));
// }
// }
+//
+package scanner
import (
"utf8";
@@ -36,12 +36,17 @@ import (
// If a syntax error is encountered, Error() is called with the exact
// token position (the byte position of the token in the source) and the
// error message.
-\n+//
type ErrorHandler interface {
Error(pos int, msg string);
}
+// A Scanner holds the scanner's internal state while processing
+// a given text. It can be allocated as part of another data
+// structure but must be initialized via Init() before use.
+// See also the package comment for a sample use.
+//
type Scanner struct {
// immutable state
src []byte; // source
@@ -94,13 +99,12 @@ func (S *Scanner) next() {
}
-// Initialize the scanner.
+// Init() prepares the scanner S to tokenize the text src. Calls to Scan()
+// will use the error handler err if they encounter a syntax error. The boolean
+// scan_comments specifies whether newline characters and comments should be
+// recognized and returned by Scan as token.COMMENT. If scan_comments is false,
+// they are treated as white space and ignored.
//
-// The error handler (err) is called when an illegal token is encountered.
-// If scan_comments is set to true, newline characters ('\n') and comments
-// are recognized as token.COMMENT, otherwise they are treated as white
-// space and ignored.
-\n func (S *Scanner) Init(src []byte, err ErrorHandler, scan_comments bool) {
S.src = src;
S.err = err;
@@ -397,10 +401,11 @@ func (S *Scanner) switch4(tok0, tok1, ch2, tok2, tok3 int) int {
}
-// Scans the next token. Returns the token byte position in the source,\n-// its token value, and the corresponding literal text if the token is\n-// an identifier or basic type literal (token.IsLiteral(tok) == true).\n-\n+// Scan() scans the next token and returns the token byte position in the\n+// source, its token value, and the corresponding literal text if the token\n+// is an identifier, basic type literal (token.IsLiteral(tok) == true), or\n+// comment.\n+//
func (S *Scanner) Scan() (pos, tok int, lit []byte) {
scan_again:
S.skipWhitespace();
コアとなるコードの解説
このコミットは、Go言語のscanner
パッケージのドキュメンテーションを改善するためのものです。コードのロジック自体には変更がなく、主にコメントの追加、修正、移動が行われています。
-
パッケージコメントの配置:
package scanner
の宣言がファイルの先頭からimport
文の後に移動し、その直前に//
で始まるパッケージ全体の説明コメントが配置されました。これはGoのドキュメンテーションツール(go doc
)がパッケージコメントを正しく認識し、生成されるドキュメントに含めるための標準的な慣習です。- パッケージの利用例を示すコードスニペットも更新され、より具体的で分かりやすいものになっています。
-
ErrorHandler
インターフェースのコメント:ErrorHandler
インターフェースの役割について、より詳細な説明が追加されました。これにより、このインターフェースがどのようにエラー処理に使用されるかが明確になります。
-
Scanner
構造体のコメント:Scanner
構造体の定義の直前に、その目的と使用方法に関する新しいコメントが追加されました。特に、「使用前にInit()
を介して初期化されなければならない」という重要な利用規約が明記されています。また、パッケージコメントのサンプル使用例を参照するように促すことで、関連するドキュメントへの誘導も行われています。
-
Init
関数のコメント:Init
関数のコメントが全面的に書き直されました。変更前は簡潔な説明でしたが、変更後は引数(src
,err
,scan_comments
)のそれぞれの役割と、それらがスキャナーの動作にどのように影響するかについて、より詳細な説明が提供されています。特に、scan_comments
がfalse
の場合にコメントや改行が空白として扱われる点が明確にされました。
-
Scan
関数のコメント:Scan
関数のコメントも更新され、戻り値(pos
,tok
,lit
)がそれぞれ何を表すのか、そしてlit
がどのような場合に返されるのか(識別子、基本型リテラル、またはコメント)がより具体的に記述されています。特に「コメント」が追加されたことで、scan_comments
がtrue
の場合のScan
関数の振る舞いがより明確になりました。
これらの変更は、Go言語の初期段階において、コードの可読性と保守性を高め、将来の利用者がscanner
パッケージをより効果的に利用できるようにするための、ドキュメンテーションの洗練作業の一環です。
関連リンク
- Go言語の公式ドキュメント: https://go.dev/doc/
- Go言語の
go/scanner
パッケージ(現在のバージョン): https://pkg.go.dev/go/scanner
参考にした情報源リンク
- Go言語のリリース履歴(2009年の情報を含む): https://go.dev/doc/devel/release
- Go言語のドキュメンテーションの書き方に関するガイドライン: https://go.dev/doc/effective_go#commentary
- 字句解析に関する一般的な情報 (Wikipedia): https://ja.wikipedia.org/wiki/%E5%AD%97%E5%8F%A5%E8%A7%A3%E6%9E%90
- Go言語の
go doc
コマンドについて: https://go.dev/cmd/go/#hdr-Show_documentation_for_package_or_symbol