[インデックス 1897] ファイルの概要
このコミットは、Go言語の標準ライブラリの一部であるscanner
パッケージ(src/lib/go/scanner.go
)と、そのテストファイル(src/lib/go/scanner_test.go
)に対する変更を含んでいます。scanner
パッケージは、ソースコードを字句解析(トークン化)するための機能を提供します。具体的には、入力されたバイト列をGo言語のキーワード、識別子、演算子、リテラルなどの意味のある最小単位(トークン)に分解する役割を担います。
このコミットの主な目的は、scanner
の柔軟性を高め、エラーハンドリングの挙動を改善することにあります。具体的には、エラーハンドラが設定されていない場合でもスキャナーが動作し続けることを許可し、発生したエラーの総数を追跡するためのカウンタを導入しています。これにより、より堅牢で、かつエラー発生時にも処理を継続できるような字句解析器の実現を目指しています。
コミット
minor tweaks:
- permit scanner to run w/o error handler
- provide an error counter
R=iant
DELTA=43 (25 added, 0 deleted, 18 changed)
OCL=26804
CL=26812
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/3f9da829041dfaa1ee0a15b4f24ae94d7ad15a0e
元コミット内容
commit 3f9da829041dfaa1ee0a15b4f24ae94d7ad15a0e
Author: Robert Griesemer <gri@golang.org>
Date: Thu Mar 26 22:13:49 2009 -0700
minor tweaks:
- permit scanner to run w/o error handler
- provide an error counter
R=iant
DELTA=43 (25 added, 0 deleted, 18 changed)
OCL=26804
CL=26812
---
src/lib/go/scanner.go | 42 ++++++++++++++++++++++++++++++------------
src/lib/go/scanner_test.go | 13 ++++++++++---\n 2 files changed, 40 insertions(+), 15 deletions(-)
diff --git a/src/lib/go/scanner.go b/src/lib/go/scanner.go
index 8b51a3e498..e35cc5c722 100644
--- a/src/lib/go/scanner.go
+++ b/src/lib/go/scanner.go
@@ -16,10 +16,10 @@ import (
)
-// An implementation of an ErrorHandler must be provided to the Scanner.\n-// If a syntax error is encountered, Error is called with a position and\n-// an error message. The position points to the beginning of the offending\n-// token.\n+// An implementation of an ErrorHandler may be provided to the Scanner.\n+// If a syntax error is encountered and a handler was installed, Error\n+// is called with a position and an error message. The position points\n+// to the beginning of the offending token.\n //
type ErrorHandler interface {
Error(pos token.Position, msg string);
@@ -34,13 +34,16 @@ type ErrorHandler interface {
type Scanner struct {
// immutable state
src []byte; // source
-\terr ErrorHandler; // error reporting\n+\terr ErrorHandler; // error reporting; or nil\n scan_comments bool; // if set, comments are reported as tokens
// scanning state
pos token.Position; // previous reading position (position before ch)
offset int; // current reading offset (position after ch)
ch int; // one char look-ahead
+\n+\t// public state - ok to modify\n+\tErrorCount int; // number of errors encountered\n }\n
@@ -70,10 +73,12 @@ func (S *Scanner) next() {
// 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\n-// scan_comments specifies whether comments should be recognized and returned\n-// by Scan as token.COMMENT. If scan_comments is false, they are treated as\n-// white space and ignored.\n+// will use the error handler err if they encounter a syntax error and\n+// err is not nil. Also, for each error encountered, the Scanner field\n+// ErrorCount is incremented by one. The boolean scan_comments specifies\n+// whether comments should be recognized and returned by Scan as COMMENT\n+// tokens. If scan_comments is false, they are treated as white space and\n+// ignored.\n //
func (S *Scanner) Init(src []byte, err ErrorHandler, scan_comments bool) {
// Explicitly initialize all fields since a scanner may be reused.
//
@@ -82,6 +87,7 @@ func (S *Scanner) Init(src []byte, err ErrorHandler, scan_comments bool) {
S.scan_comments = scan_comments;
S.pos = token.Position{0, 1, 0};
S.offset = 0;
+\tS.ErrorCount = 0;\n S.next();
}\n
@@ -105,7 +111,10 @@ func charString(ch int) string {
func (S *Scanner) error(pos token.Position, msg string) {
-\tS.err.Error(pos, msg);\n+\tif S.err != nil {\n+\t\tS.err.Error(pos, msg);\n+\t}\n+\tS.ErrorCount++;\n }\n
@@ -374,6 +383,13 @@ func (S *Scanner) switch4(tok0, tok1 token.Token, ch2 int, tok2, tok3 token.Toke
// the token tok, and the literal text lit corresponding to the
// token. The source end is indicated by token.EOF.
//
+// For more tolerant parsing, Scan will return a valid token if
+// possible even if a syntax error was encountered. Thus, even
+// if the resulting token sequence contains no illegal tokens,
+// a client may not assume that no error occurred. Instead it
+// must check the scanner\'s ErrorCount or the number of calls
+// of the error handler, if there was one installed.\n+//
func (S *Scanner) Scan() (pos token.Position, tok token.Token, lit []byte) {
scan_again:
// skip white space
@@ -462,12 +478,14 @@ scan_again:
// Tokenize calls a function f with the token position, token value, and token
// text for each token in the source src. The other parameters have the same
// meaning as for the Init function. Tokenize keeps scanning until f returns
-// false (usually when the token value is token.EOF).\n+// false (usually when the token value is token.EOF). The result is the number\n+// of errors encountered.\n //
-func Tokenize(src []byte, err ErrorHandler, scan_comments bool, f func (pos token.Position, tok token.Token, lit []byte) bool) {\n+func Tokenize(src []byte, err ErrorHandler, scan_comments bool, f func (pos token.Position, tok token.Token, lit []byte) bool) int {\n var s Scanner;\n s.Init(src, err, scan_comments);\n for f(s.Scan()) {\n // action happens in f\n }\n+\treturn s.ErrorCount;\n }\ndiff --git a/src/lib/go/scanner_test.go b/src/lib/go/scanner_test.go
index bbe0b7602d..f6edea10a9 100644
--- a/src/lib/go/scanner_test.go
+++ b/src/lib/go/scanner_test.go
@@ -188,7 +188,7 @@ func TestScan(t *testing.T) {
// verify scan
index := 0;
eloc := token.Position{0, 1, 1};
-\tscanner.Tokenize(io.StringBytes(src), &TestErrorHandler{t}, true,\n+\tnerrors := scanner.TokenBytes(src), &TestErrorHandler{t}, true,\n func (pos token.Position, tok token.Token, litb []byte) bool {
\t\te := elt{token.EOF, \"\", special};
\t\tif index < len(tokens) {
@@ -223,6 +223,9 @@ func TestScan(t *testing.T) {
\t\treturn tok != token.EOF;
\t}
);\n+\tif nerrors != 0 {\n+\t\tt.Errorf(\"found %d errors\", nerrors);\n+\t}\n }\n
@@ -231,7 +234,7 @@ func TestInit(t *testing.T) {
var s scanner.Scanner;
// 1st init
-\ts.Init(io.StringBytes(\"if true { }\"), &TestErrorHandler{t}, false);\n+\ts.Init(io.StringBytes(\"if true { }\"), nil, false);\n s.Scan(); // if
s.Scan(); // true
pos, tok, lit := s.Scan(); // {
@@ -240,9 +243,13 @@ func TestInit(t *testing.T) {
}\n
// 2nd init
-\ts.Init(io.StringBytes(\"go true { ]\"), &TestErrorHandler{t}, false);\n+\ts.Init(io.StringBytes(\"go true { ]\"), nil, false);\n pos, tok, lit = s.Scan(); // go
if tok != token.GO {\n \t\tt.Errorf(\"bad token: got %s, expected %s\", tok.String(), token.GO);\n }\n+\n+\tif s.ErrorCount != 0 {\n+\t\tt.Errorf(\"found %d errors\", s.ErrorCount);\n+\t}\n }\n
変更の背景
このコミットが行われた2009年3月は、Go言語がまだ一般に公開される前の初期開発段階にありました。この時期のコミットは、言語の基本的な設計や標準ライブラリの基盤が形成されていく過程を反映しています。
字句解析器(スキャナー)は、コンパイラやインタプリタのフロントエンドにおいて非常に重要なコンポーネントです。初期の設計では、scanner
パッケージのInit
メソッドはErrorHandler
インターフェースの実装を必須としていました。これは、字句解析中にエラーが発生した場合に、そのエラーを報告するためのコールバックメカニズムを提供するためです。
しかし、すべての利用シナリオにおいてエラーハンドラが必須であるとは限りません。例えば、単にトークン列を生成したいだけで、エラーが発生しても処理を中断せずに続行したい場合や、エラーの報告は後でまとめて行いたい場合などです。また、エラーが発生した回数をプログラム的に取得したいというニーズも考えられます。
このコミットは、このような背景から、scanner
の柔軟性と実用性を向上させるために導入されました。具体的には、以下の2つの主要な改善が図られています。
- エラーハンドラの任意化:
ErrorHandler
の実装を必須ではなく任意とすることで、ユーザーがエラーハンドリングの挙動をより細かく制御できるようになります。エラーハンドラがnil
の場合でもスキャナーがクラッシュすることなく動作を継続できるようになります。 - エラーカウンタの導入: 字句解析中に発生したエラーの総数を追跡するための
ErrorCount
フィールドをScanner
構造体に追加することで、エラーの発生状況をプログラム的に把握できるようになります。これにより、エラーハンドラを介した報告とは別に、エラーの統計情報を収集することが可能になります。
これらの変更は、Go言語の設計哲学である「シンプルさ」と「実用性」を反映しており、開発者がscanner
をより多様な状況で利用できるようにするための重要なステップでした。
前提知識の解説
このコミットの変更内容を理解するためには、以下の概念について基本的な知識が必要です。
1. 字句解析 (Lexical Analysis / Tokenization)
字句解析は、コンパイラやインタプリタの最初のフェーズです。ソースコードの文字列を読み込み、それを意味のある最小単位である「トークン」の列に変換します。例えば、if x > 0 { ... }
というコードは、if
(キーワード), x
(識別子), >
(演算子), 0
(整数リテラル), {
(区切り文字) といったトークンに分解されます。
Go言語では、text/scanner
パッケージがこの字句解析の機能を提供します。
2. token
パッケージ
Go言語のtoken
パッケージは、字句解析器が生成するトークンの種類を定義する定数(例: token.IDENT
、token.INT
、token.ADD
など)や、ソースコード内の位置情報(行番号、列番号、オフセットなど)を表すtoken.Position
構造体を提供します。
3. scanner
パッケージ
scanner
パッケージは、Go言語のソースコード(または類似のテキスト)をトークンに分解するためのScanner
構造体を提供します。主な機能は以下の通りです。
Scanner
構造体: 字句解析の状態(現在の読み取り位置、次の文字など)を保持します。Init
メソッド: スキャナーを初期化し、解析対象のソースコード、エラーハンドラ、コメントをトークンとして扱うかどうかの設定を行います。Scan
メソッド: 次のトークンを読み込み、その位置、種類、リテラル値を返します。ErrorHandler
インターフェース: 字句解析中にエラーが発生した場合に呼び出されるError
メソッドを定義します。
4. インターフェース (Interfaces)
Go言語のインターフェースは、メソッドのシグネチャの集合を定義します。特定のインターフェースを実装する型は、そのインターフェースが定義するすべてのメソッドを提供する必要があります。ErrorHandler
は、Error(pos token.Position, msg string)
というメソッドを持つインターフェースです。
5. エラーハンドリングのパターン
プログラミングにおけるエラーハンドリングには様々なパターンがあります。
- 即時報告: エラーが発生した時点で、登録されたハンドラにエラーを報告し、必要に応じて処理を中断します。
- エラーコード/カウンタ: エラーが発生しても処理を継続し、エラーの有無や数を戻り値や内部カウンタで示します。呼び出し元が後でこれらの情報をチェックします。
- パニック/リカバリ: Go言語特有のメカニズムで、予期せぬエラーが発生した場合にパニックを発生させ、
defer
とrecover
を使って処理を回復させることができます。
このコミットは、scanner
において「即時報告」と「エラーコード/カウンタ」の両方のアプローチを柔軟に選択できるようにするものです。
技術的詳細
このコミットは、scanner
パッケージのScanner
構造体と関連するメソッドに、以下の重要な技術的変更を加えています。
1. ErrorHandler
の任意化
変更前は、ErrorHandler
インターフェースの実装がScanner
のInit
メソッドに必須でした。これは、scanner.go
のコメントで「An implementation of an ErrorHandler must be provided to the Scanner.」と明記されていました。
変更後は、このコメントが「An implementation of an ErrorHandler may be provided to the Scanner.」と修正され、エラーハンドラが任意であることが示されています。
これを実現するために、Scanner
構造体のerr
フィールドのコメントが「// error reporting; or nil
」に変更され、nil
が許容されるようになりました。
そして、error
メソッド(スキャナー内部でエラーを報告する際に呼び出される)において、以下のチェックが追加されました。
func (S *Scanner) error(pos token.Position, msg string) {
if S.err != nil { // エラーハンドラがnilでない場合のみ呼び出す
S.err.Error(pos, msg);
}
S.ErrorCount++; // エラーカウンタは常にインクリメント
}
この変更により、S.err
がnil
の場合でもS.err.Error
が呼び出されなくなり、スキャナーがパニックを起こすことなく動作を継続できるようになりました。
2. エラーカウンタ ErrorCount
の導入
Scanner
構造体にErrorCount int
という新しい公開フィールドが追加されました。このフィールドは、字句解析中に発生したエラーの総数を保持します。
- 初期化:
Scanner.Init
メソッド内でS.ErrorCount = 0;
と初期化されます。これにより、スキャナーが再利用される際にもエラーカウントがリセットされることが保証されます。 - インクリメント:
error
メソッドが呼び出されるたびに、S.ErrorCount++
によってインクリメントされます。これは、エラーハンドラが設定されているかどうかにかかわらず、常に実行されます。
このErrorCount
フィールドは「// public state - ok to modify
」とコメントされており、外部から参照・変更可能であることが示唆されていますが、通常は参照のみに利用されます。
3. Scan
メソッドの挙動とドキュメントの変更
Scan
メソッドのドキュメントに、以下の重要な説明が追加されました。
// For more tolerant parsing, Scan will return a valid token if
// possible even if a syntax error was encountered. Thus, even
// if the resulting token sequence contains no illegal tokens,
// a client may not assume that no error occurred. Instead it
// must check the scanner's ErrorCount or the number of calls
// of the error handler, if there was one installed.
これは、スキャナーがエラーに遭遇した場合でも、可能な限り有効なトークンを返そうとする「より寛容なパース」の考え方を示しています。したがって、Scan
メソッドがtoken.ILLEGAL
のようなエラーを示すトークンを返さなかったとしても、エラーが発生していないとは限りません。クライアントは、エラーの有無を確認するために、Scanner.ErrorCount
をチェックするか、設定されている場合はエラーハンドラの呼び出し回数を数える必要があることを明示しています。
4. Tokenize
関数の戻り値の変更
Tokenize
関数は、ソースコードをトークン化し、各トークンに対してコールバック関数f
を呼び出すユーティリティ関数です。変更前はvoid
(何も返さない)でしたが、変更後はint
を返すようになりました。
// 変更前:
// func Tokenize(src []byte, err ErrorHandler, scan_comments bool, f func (pos token.Position, tok token.Token, lit []byte) bool) {
// 変更後:
func Tokenize(src []byte, err ErrorHandler, scan_comments bool, f func (pos token.Position, tok token.Token, lit []byte) bool) int {
var s Scanner;
s.Init(src, err, scan_comments);
for f(s.Scan()) {
// action happens in f
}
return s.ErrorCount; // スキャナーのエラーカウントを返す
}
この変更により、Tokenize
関数を呼び出した側は、字句解析が完了した後に発生したエラーの総数を直接取得できるようになりました。これは、エラーハンドラを登録しない場合でもエラーの発生状況を把握できるという、ErrorCount
導入のメリットを最大限に活用するための変更です。
5. テストコードの変更 (scanner_test.go
)
テストコードもこれらの変更に合わせて更新されています。
TestScan
関数では、scanner.Tokenize
の戻り値(エラーカウント)を受け取るようになり、その値が0でない場合にテストを失敗させるアサーションが追加されました。TestInit
関数では、s.Init
の呼び出しでエラーハンドラとしてnil
を渡すケースが追加され、その後にs.ErrorCount
が0であることを確認するアサーションが追加されました。これにより、エラーハンドラがnil
の場合でもスキャナーが正しく初期化され、エラーカウントが期待通りに動作することが検証されています。
これらの変更は、Go言語の字句解析器がより柔軟で、エラー耐性があり、かつエラー情報をプログラム的に利用しやすいように進化していることを示しています。
コアとなるコードの変更箇所
このコミットにおけるコアとなるコードの変更箇所は、主にsrc/lib/go/scanner.go
ファイルに集中しています。
-
ErrorHandler
インターフェースのコメント変更:--- a/src/lib/go/scanner.go +++ b/src/lib/go/scanner.go @@ -16,10 +16,10 @@ import ( ) -// An implementation of an ErrorHandler must be provided to the Scanner. -// If a syntax error is encountered, Error is called with a position and -// an error message. The position points to the beginning of the offending -// token. +// An implementation of an ErrorHandler may be provided to the Scanner. +// If a syntax error is encountered and a handler was installed, Error +// is called with a position and an error message. The position points +// to the beginning of the offending token. // type ErrorHandler interface { Error(pos token.Position, msg string);
-
Scanner
構造体へのErrorCount
フィールド追加とerr
フィールドのコメント変更:--- a/src/lib/go/scanner.go +++ b/src/lib/go/scanner.go @@ -34,13 +34,16 @@ type ErrorHandler interface { type Scanner struct { // immutable state src []byte; // source -\terr ErrorHandler; // error reporting +\terr ErrorHandler; // error reporting; or nil scan_comments bool; // if set, comments are reported as tokens // scanning state pos token.Position; // previous reading position (position before ch) offset int; // current reading offset (position after ch) ch int; // one char look-ahead +\n+\t// public state - ok to modify +\tErrorCount int; // number of errors encountered }\n
-
Scanner.Init
メソッドでのErrorCount
初期化とコメント変更:--- a/src/lib/go/scanner.go +++ b/src/lib/go/scanner.go @@ -70,10 +73,12 @@ func (S *Scanner) next() { // 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 comments should be recognized and returned -// by Scan as token.COMMENT. If scan_comments is false, they are treated as -// white space and ignored. +// will use the error handler err if they encounter a syntax error and +// err is not nil. Also, for each error encountered, the Scanner field +// ErrorCount is incremented by one. The boolean scan_comments specifies +// whether comments should be recognized and returned by Scan as COMMENT +// tokens. If scan_comments is false, they are treated as white space and +// ignored. // func (S *Scanner) Init(src []byte, err ErrorHandler, scan_comments bool) { // Explicitly initialize all fields since a scanner may be reused. // @@ -82,6 +87,7 @@ func (S *Scanner) Init(src []byte, err ErrorHandler, scan_comments bool) { S.scan_comments = scan_comments; S.pos = token.Position{0, 1, 0}; S.offset = 0; +\tS.ErrorCount = 0;\n S.next(); }\n
-
Scanner.error
メソッドでのエラーハンドラ呼び出し条件追加とErrorCount
インクリメント:--- a/src/lib/go/scanner.go +++ b/src/lib/go/scanner.go @@ -105,7 +111,10 @@ func charString(ch int) string { func (S *Scanner) error(pos token.Position, msg string) { -\tS.err.Error(pos, msg);\n+\tif S.err != nil {\n+\t\tS.err.Error(pos, msg);\n+\t}\n+\tS.ErrorCount++;\n }\n
-
Scanner.Scan
メソッドのコメント変更:--- a/src/lib/go/scanner.go +++ b/src/lib/go/scanner.go @@ -374,6 +383,13 @@ func (S *Scanner) switch4(tok0, tok1 token.Token, ch2 int, tok2, tok3 token.Toke // the token tok, and the literal text lit corresponding to the // token. The source end is indicated by token.EOF. // +// For more tolerant parsing, Scan will return a valid token if +// possible even if a syntax error was encountered. Thus, even +// if the resulting token sequence contains no illegal tokens, +// a client may not assume that no error occurred. Instead it +// must check the scanner\'s ErrorCount or the number of calls +// of the error handler, if there was one installed.\n+// func (S *Scanner) Scan() (pos token.Position, tok token.Token, lit []byte) { scan_again: // skip white space
-
Tokenize
関数の戻り値の型変更とErrorCount
の返却:--- a/src/lib/go/scanner.go +++ b/src/lib/go/scanner.go @@ -462,12 +478,14 @@ scan_again: // Tokenize calls a function f with the token position, token value, and token // text for each token in the source src. The other parameters have the same // meaning as for the Init function. Tokenize keeps scanning until f returns -// false (usually when the token value is token.EOF).\n+// false (usually when the token value is token.EOF). The result is the number\n+// of errors encountered.\n // -func Tokenize(src []byte, err ErrorHandler, scan_comments bool, f func (pos token.Position, tok token.Token, lit []byte) bool) {\n+func Tokenize(src []byte, err ErrorHandler, scan_comments bool, f func (pos token.Position, tok token.Token, lit []byte) bool) int {\n var s Scanner;\n s.Init(src, err, scan_comments);\n for f(s.Scan()) {\n // action happens in f }\n+\treturn s.ErrorCount;\n }\n ```
コアとなるコードの解説
上記の変更箇所は、scanner
パッケージの動作と利用方法に直接影響を与える重要な部分です。
-
ErrorHandler
インターフェースのコメント変更:- 変更前は、
ErrorHandler
の実装がScanner
に「必須」であると明記されていました。これは、エラーハンドラを提供しないとスキャナーが正しく動作しない、あるいはエラー時にパニックを起こす可能性を示唆していました。 - 変更後は、「任意」であると修正されました。これは、エラーハンドラが
nil
であってもスキャナーが動作し続けることを意図していることを明確に示しています。
- 変更前は、
-
Scanner
構造体へのErrorCount
フィールド追加とerr
フィールドのコメント変更:Scanner
構造体にErrorCount int
という新しいフィールドが追加されました。これは、字句解析中に発生したエラーの総数を追跡するためのカウンタです。このカウンタは、エラーハンドラが設定されているかどうかにかかわらず、常にインクリメントされます。これにより、エラーハンドラを介した詳細な報告とは別に、エラーの発生回数を簡単に取得できるようになります。err ErrorHandler
フィールドのコメントが「// error reporting; or nil
」に変更されました。これは、err
フィールドにnil
を代入することが許容され、その場合でもスキャナーが正常に動作することを明示しています。
-
Scanner.Init
メソッドでのErrorCount
初期化とコメント変更:S.ErrorCount = 0;
という行が追加され、Scanner
が初期化される際にErrorCount
が必ず0にリセットされるようになりました。これにより、Scanner
インスタンスが再利用される場合でも、以前の解析結果によるエラーカウントが残らないことが保証されます。- コメントも更新され、
err
がnil
でない場合にエラーハンドラが使用されることと、ErrorCount
がインクリメントされることが明記されました。
-
Scanner.error
メソッドでのエラーハンドラ呼び出し条件追加とErrorCount
インクリメント:if S.err != nil { S.err.Error(pos, msg); }
という条件分岐が追加されました。これにより、S.err
(エラーハンドラ)がnil
の場合にはError
メソッドが呼び出されなくなり、nil
ポインタデリファレンスによるパニックを防ぎます。S.ErrorCount++;
という行が追加され、error
メソッドが呼び出されるたびに(つまり、字句解析エラーが検出されるたびに)ErrorCount
がインクリメントされるようになりました。これは、エラーハンドラの有無にかかわらず、エラーの総数を正確に追跡するための重要な変更です。
-
Scanner.Scan
メソッドのコメント変更:Scan
メソッドのドキュメントに、スキャナーが「より寛容なパース」を行うこと、つまりエラーが発生しても可能な限り有効なトークンを返すように努めることが追記されました。- これにより、
Scan
がエラーを示すトークンを返さなかったとしても、エラーが発生していないとは限らないため、クライアントはScanner.ErrorCount
またはエラーハンドラの呼び出し回数をチェックしてエラーの有無を確認する必要があることが強調されています。これは、エラーハンドラを任意にしたことと、エラーカウンタを導入したことの利用方法を明確にするものです。
-
Tokenize
関数の戻り値の型変更とErrorCount
の返却:Tokenize
関数の戻り値の型がvoid
からint
に変更され、s.ErrorCount
(字句解析中に発生したエラーの総数)を返すようになりました。- これにより、
Tokenize
関数を呼び出す側は、エラーハンドラを登録しなくても、字句解析の完了後にエラーの総数を直接取得できるようになり、エラー処理の柔軟性が向上しました。
これらの変更は、Go言語の字句解析器がより堅牢で、柔軟なエラーハンドリングを提供し、開発者がエラー情報をより簡単に利用できるようにするための基盤を築いたと言えます。
関連リンク
- Go言語の
text/scanner
パッケージのドキュメント (現在のバージョン): https://pkg.go.dev/text/scanner - Go言語の
go/token
パッケージのドキュメント (現在のバージョン): https://pkg.go.dev/go/token - Go言語の初期コミット履歴 (GitHub): https://github.com/golang/go/commits/master
参考にした情報源リンク
- Go言語の公式ドキュメント (
text/scanner
,go/token
): 上記の関連リンクに記載。 - Go言語のGitHubリポジトリ: コミット履歴とソースコードの差分を確認するために使用。
- 字句解析に関する一般的な情報 (コンパイラ理論): 字句解析の概念、エラーハンドリングのパターンを理解するために参照。
- 例: Wikipediaの「字句解析」の項目など。 https://ja.wikipedia.org/wiki/%E5%AD%97%E5%A4%A0%E8%A7%A3%E6%9E%90
- Go言語の初期開発に関する議論やメーリングリストのアーカイブ (もしあれば): このコミットの背景にある具体的な議論を理解するために役立つ可能性があるが、今回は直接参照せず、コミットメッセージとコードの変更から推測した。
- Go Nutsメーリングリストアーカイブ (例): https://groups.google.com/g/golang-nuts (特定のコミットに関する議論を特定するには、より詳細な検索が必要)