[インデックス 16292] ファイルの概要
このコミットは、Goコンパイラ(cmd/gc
)におけるimport
ステートメントの構文エラーメッセージを改善するものです。具体的には、import testing
のように、インポートパスが引用符で囲まれていない場合に、より分かりやすいエラーメッセージ「missing import path; require quoted string
」を出力するように変更されました。これにより、開発者がGoのインポート構文の誤りを迅速に特定し、修正できるようになります。
コミット
commit 3ac5d54cf91d70571cc68be1361103e11c5d3285
Author: Shenghou Ma <minux.ma@gmail.com>
Date: Wed May 15 04:19:19 2013 +0800
cmd/gc: improve syntax error for "import testing"
for this program:
package A
import testing
old diagnostics:
pkg.go:2: syntax error: unexpected semicolon or newline, expecting string literal
now:
pkg.go:2: syntax error: missing import path; require quoted string
Fixes #5332.
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/9393043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/3ac5d54cf91d70571cc68be1361103e11c5d3285
元コミット内容
cmd/gc: improve syntax error for "import testing"
for this program:
package A
import testing
old diagnostics:
pkg.go:2: syntax error: unexpected semicolon or newline, expecting string literal
now:
pkg.go:2: syntax error: missing import path; require quoted string
Fixes #5332.
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/9393043
変更の背景
この変更は、Go言語のimport
ステートメントにおいて、インポートパスが引用符で囲まれていない場合に、コンパイラが生成するエラーメッセージが不明瞭であった問題を解決するために行われました。
以前のGoコンパイラでは、以下のようなコードがあった場合:
package A
import testing
コンパイラは「syntax error: unexpected semicolon or newline, expecting string literal
」というエラーを出力していました。このメッセージは、import
キーワードの後に文字列リテラル(引用符で囲まれたパス)が期待されているにもかかわらず、testing
という識別子(LNAME
)が来たために、コンパイラのパーサーが予期せぬセミコロンまたは改行を検出したと解釈した結果です。しかし、このエラーメッセージは、問題の根本原因が「インポートパスが引用符で囲まれていないこと」であることを直接的に示していませんでした。
開発者にとって、このような曖昧なエラーメッセージは、特にGo言語に不慣れな場合、デバッグを困難にする可能性があります。Go言語の設計哲学の一つに「明確なエラーメッセージ」があります。このコミットは、その哲学に沿って、より具体的で分かりやすいエラーメッセージを提供することで、開発者の生産性向上に貢献することを目的としています。この変更は、Go issue #5332 で報告された問題に対応しています。
前提知識の解説
Go言語のimport
ステートメント
Go言語では、外部パッケージの機能を利用するためにimport
ステートメントを使用します。import
ステートメントの基本的な構文は以下の通りです。
import "path/to/package"
ここで、"path/to/package"
はインポートするパッケージのパスを文字列リテラルとして指定します。例えば、標準ライブラリのfmt
パッケージをインポートする場合はimport "fmt"
と記述します。複数のパッケージをインポートする場合は、以下のように括弧でまとめて記述することもできます。
import (
"fmt"
"net/http"
)
インポートパスは必ずダブルクォーテーション("
)で囲まれた文字列リテラルである必要があります。
Goコンパイラ(cmd/gc
)とエラーハンドリング
cmd/gc
は、Go言語の公式コンパイラの一部であり、Goソースコードをコンパイルして実行可能なバイナリを生成する役割を担っています。コンパイルプロセスには、字句解析(Lexing)、構文解析(Parsing)、型チェック(Type Checking)、最適化(Optimization)、コード生成(Code Generation)などの段階が含まれます。
構文解析の段階で、ソースコードがGo言語の文法規則に準拠しているかどうかがチェックされます。文法エラーが検出された場合、コンパイラはエラーメッセージを生成し、開発者に報告します。これらのエラーメッセージは、コンパイラのソースコード内で定義されており、特定の構文パターンとそれに対応するエラー文字列が関連付けられています。
cmd/gc
におけるエラーメッセージの定義は、主に以下のファイルで行われています。
src/cmd/gc/go.errors
: このファイルは、Goコンパイラの構文解析器(パーサー)が生成するエラーメッセージのテンプレートを定義しています。これは、Yacc/Bisonのようなパーサー生成ツールで使用されるエラー定義に似ています。各行は、特定の構文規則と、その規則が破られた場合に表示されるエラーメッセージのペアを含んでいます。src/cmd/gc/yerr.h
: このファイルは、go.errors
で定義されたエラーメッセージに対応する数値コードと、エラーメッセージ文字列自体をC言語のヘッダーファイル形式で定義しています。go.errors
がパーサーの文脈でエラーを識別するためのパターンを定義するのに対し、yerr.h
はそれらのエラーに具体的なメッセージを割り当て、コンパイラ内部で参照できるようにします。
コンパイラが構文エラーを検出すると、go.errors
内のパターンと照合し、対応するエラーメッセージをyerr.h
から取得して出力します。
技術的詳細
このコミットの技術的な核心は、Goコンパイラの構文解析器がimport
ステートメントの誤った形式を検出した際に、より適切なエラーメッセージを生成するように、エラー定義を追加した点にあります。
以前のコンパイラでは、import testing
のような記述があった場合、パーサーはimport
キーワードの後にLNAME
(識別子、この場合はtesting
)が来たことを検出します。しかし、期待されるのはLLITERAL
(文字列リテラル)でした。この不一致により、パーサーは一般的な「unexpected semicolon or newline, expecting string literal
」というエラーを発生させていました。これは、import
の後に文字列リテラルが来ない場合、パーサーが次のトークンをセミコロンや改行と誤解釈し、その後に文字列リテラルが続くことを期待するという、より一般的な構文エラーのパターンに合致していたためです。
このコミットでは、src/cmd/gc/go.errors
に新しいエラーパターンが追加されました。
% loadsys package LIMPORT LNAME ';'
"missing import path; require quoted string",
この行は、以下のような構文パターンを検出した場合に特定のエラーメッセージを出力するようにコンパイラに指示します。
% loadsys package
: これは、Goコンパイラの内部的なエラー定義の構文の一部です。LIMPORT
:import
キーワードを表す字句トークン。LNAME
: 識別子(この場合はtesting
)。';'
: セミコロン。Go言語では、ステートメントの終端にセミコロンを置くことができますが、通常は改行で代用されます。しかし、パーサーの内部的な処理では、このような状況でセミコロンが補完されることがあります。
この新しいパターンは、「import
キーワードの直後に識別子(LNAME
)が来て、その後にセミコロン(または暗黙のセミコロン)が続く」という特定の誤ったimport
構文を正確に捉えます。このパターンに合致した場合、コンパイラは「missing import path; require quoted string
」という、より具体的で分かりやすいエラーメッセージを出力するようになります。
同時に、src/cmd/gc/yerr.h
にも対応するエラーコードとメッセージが追加されました。
32, ';',
"missing import path; require quoted string",
これは、go.errors
で定義された新しいエラーパターンに対応する、コンパイラ内部で使用されるエラーID(32
)と、そのエラーメッセージ文字列を関連付けています。これにより、コンパイラは新しいエラーパターンを検出した際に、この特定のメッセージを正確に参照して出力できるようになります。
この変更により、コンパイラは一般的な構文エラーとして処理するのではなく、import
ステートメントにおける特定の誤用を識別し、その原因を直接的に示すエラーメッセージを提供できるようになりました。これは、コンパイラのエラー診断能力を向上させ、開発者のデバッグ体験を改善する上で重要な改善です。
コアとなるコードの変更箇所
このコミットによるコードの変更は、以下の2つのファイルに集中しています。
-
src/cmd/gc/go.errors
--- a/src/cmd/gc/go.errors +++ b/src/cmd/gc/go.errors @@ -17,6 +17,9 @@ static struct { % loadsys package LIMPORT '(' LLITERAL import_package import_there ',' "unexpected comma during import block", + % loadsys package LIMPORT LNAME ';' + "missing import path; require quoted string", + % loadsys package imports LFUNC LNAME '(' ')' '{' LIF if_header ';' "unexpected semicolon or newline before {",
このファイルに、新しいエラーパターンとそれに対応するエラーメッセージの定義が追加されました。
-
src/cmd/gc/yerr.h
--- a/src/cmd/gc/yerr.h +++ b/src/cmd/gc/yerr.h @@ -17,6 +17,9 @@ static struct { 221, ',', "unexpected comma during import block", + 32, ';', + "missing import path; require quoted string", + 377, ';', "unexpected semicolon or newline before {",
このファイルに、
go.errors
で追加された新しいエラーメッセージに対応する数値コードとメッセージ文字列が追加されました。
コアとなるコードの解説
src/cmd/gc/go.errors
の変更
追加された行:
% loadsys package LIMPORT LNAME ';'
"missing import path; require quoted string",
この行は、Goコンパイラのパーサーが特定の構文パターンを検出したときに、特定のエラーメッセージを生成するためのルールを定義しています。
% loadsys package
: これは、Goコンパイラの内部的なエラー定義の構文の一部であり、パーサーがパッケージレベルの構文エラーを処理する方法に関連しています。LIMPORT
: 字句解析器(lexer)によって識別されるimport
キーワードのトークンです。LNAME
: 字句解析器によって識別される識別子(変数名、関数名など)のトークンです。このコンテキストでは、import testing
のtesting
がこれに該当します。';'
: セミコロンのトークンです。Go言語では、ステートメントの終わりにセミコロンを省略できますが、パーサーは内部的に改行をセミコロンとして解釈(自動セミコロン挿入)することがあります。このパターンは、import LNAME
の後に暗黙的または明示的なセミコロンが続く状況を捉えます。"missing import path; require quoted string"
: 上記のパターンが検出された場合に表示されるエラーメッセージです。このメッセージは、インポートパスが不足しており、引用符で囲まれた文字列が必要であることを明確に示しています。
この追加により、コンパイラはimport
の後に引用符で囲まれていない識別子がある場合に、より的確なエラーメッセージを出力できるようになりました。
src/cmd/gc/yerr.h
の変更
追加された行:
32, ';',
"missing import path; require quoted string",
この行は、C言語のヘッダーファイル形式で、コンパイラ内部で使用されるエラーコードとそれに対応するエラーメッセージを定義しています。
32
: これは、新しく追加されたエラーメッセージに割り当てられた一意の数値IDです。go.errors
で定義されたパターンが検出されると、このIDが参照されます。';'
: このエラーが関連するトークンを示しています。この場合、import LNAME
の後に続くセミコロン(または自動挿入されたセミコロン)がエラーのトリガーとなるトークンの一つであることを示唆しています。"missing import path; require quoted string"
: 実際にユーザーに表示されるエラーメッセージ文字列です。
これらの変更は、Goコンパイラのフロントエンドにおけるエラー診断の精度を向上させ、開発者がGo言語の構文規則をより迅速に理解し、誤りを修正できるようにするためのものです。
関連リンク
- Go Issue #5332: cmd/gc: improve syntax error for "import testing"
- Go CL 9393043: cmd/gc: improve syntax error for "import testing"
参考にした情報源リンク
- Go言語の公式ドキュメント: https://go.dev/doc/
- Goコンパイラのソースコード (特に
src/cmd/gc
ディレクトリ): https://github.com/golang/go/tree/master/src/cmd/gc - Go言語の
import
宣言に関する仕様: https://go.dev/ref/spec#Import_declarations - Yacc/Bisonのようなパーサー生成ツールのエラーハンドリングに関する一般的な情報。
- Go言語の自動セミコロン挿入ルールに関する情報。
[インデックス 16292] ファイルの概要
このコミットは、Goコンパイラ(cmd/gc
)におけるimport
ステートメントの構文エラーメッセージを改善するものです。具体的には、import testing
のように、インポートパスが引用符で囲まれていない場合に、より分かりやすいエラーメッセージ「missing import path; require quoted string
」を出力するように変更されました。これにより、開発者がGoのインポート構文の誤りを迅速に特定し、修正できるようになります。
コミット
commit 3ac5d54cf91d70571cc68be1361103e11c5d3285
Author: Shenghou Ma <minux.ma@gmail.com>
Date: Wed May 15 04:19:19 2013 +0800
cmd/gc: improve syntax error for "import testing"
for this program:
package A
import testing
old diagnostics:
pkg.go:2: syntax error: unexpected semicolon or newline, expecting string literal
now:
pkg.go:2: syntax error: missing import path; require quoted string
Fixes #5332.
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/9393043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/3ac5d54cf91d70571cc68be1361103e11c5d3285
元コミット内容
cmd/gc: improve syntax error for "import testing"
for this program:
package A
import testing
old diagnostics:
pkg.go:2: syntax error: unexpected semicolon or newline, expecting string literal
now:
pkg.go:2: syntax error: missing import path; require quoted string
Fixes #5332.
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/9393043
変更の背景
この変更は、Go言語のimport
ステートメントにおいて、インポートパスが引用符で囲まれていない場合に、コンパイラが生成するエラーメッセージが不明瞭であった問題を解決するために行われました。
以前のGoコンパイラでは、以下のようなコードがあった場合:
package A
import testing
コンパイラは「syntax error: unexpected semicolon or newline, expecting string literal
」というエラーを出力していました。このメッセージは、import
キーワードの後に文字列リテラル(引用符で囲まれたパス)が期待されているにもかかわらず、testing
という識別子(LNAME
)が来たために、コンパイラのパーサーが予期せぬセミコロンまたは改行を検出したと解釈した結果です。しかし、このエラーメッセージは、問題の根本原因が「インポートパスが引用符で囲まれていないこと」であることを直接的に示していませんでした。
開発者にとって、このような曖昧なエラーメッセージは、特にGo言語に不慣れな場合、デバッグを困難にする可能性があります。Go言語の設計哲学の一つに「明確なエラーメッセージ」があります。このコミットは、その哲学に沿って、より具体的で分かりやすいエラーメッセージを提供することで、開発者の生産性向上に貢献することを目的としています。この変更は、Go issue #5332 で報告された問題に対応しています。
前提知識の解説
Go言語のimport
ステートメント
Go言語では、外部パッケージの機能を利用するためにimport
ステートメントを使用します。import
ステートメントの基本的な構文は以下の通りです。
import "path/to/package"
ここで、"path/to/package"
はインポートするパッケージのパスを文字列リテラルとして指定します。例えば、標準ライブラリのfmt
パッケージをインポートする場合はimport "fmt"
と記述します。複数のパッケージをインポートする場合は、以下のように括弧でまとめて記述することもできます。
import (
"fmt"
"net/http"
)
インポートパスは必ずダブルクォーテーション("
)で囲まれた文字列リテラルである必要があります。
Goコンパイラ(cmd/gc
)とエラーハンドリング
cmd/gc
は、Go言語の公式コンパイラの一部であり、Goソースコードをコンパイルして実行可能なバイナリを生成する役割を担っています。コンパイルプロセスには、字句解析(Lexing)、構文解析(Parsing)、型チェック(Type Checking)、最適化(Optimization)、コード生成(Code Generation)などの段階が含まれます。
構文解析の段階で、ソースコードがGo言語の文法規則に準拠しているかどうかがチェックされます。文法エラーが検出された場合、コンパイラはエラーメッセージを生成し、開発者に報告します。これらのエラーメッセージは、コンパイラのソースコード内で定義されており、特定の構文パターンとそれに対応するエラー文字列が関連付けられています。
cmd/gc
におけるエラーメッセージの定義は、主に以下のファイルで行われていました(コミット当時の情報に基づきます)。
src/cmd/gc/go.errors
: このファイルは、Goコンパイラの構文解析器(パーサー)が生成するエラーメッセージのテンプレートを定義していました。これは、Yacc/Bisonのようなパーサー生成ツールで使用されるエラー定義に似ています。各行は、特定の構文規則と、その規則が破られた場合に表示されるエラーメッセージのペアを含んでいました。src/cmd/gc/yerr.h
: このファイルは、go.errors
で定義されたエラーメッセージに対応する数値コードと、エラーメッセージ文字列自体をC言語のヘッダーファイル形式で定義していました。go.errors
がパーサーの文脈でエラーを識別するためのパターンを定義するのに対し、yerr.h
はそれらのエラーに具体的なメッセージを割り当て、コンパイラ内部で参照できるようにしていました。
コンパイラが構文エラーを検出すると、go.errors
内のパターンと照合し、対応するエラーメッセージをyerr.h
から取得して出力していました。
技術的詳細
このコミットの技術的な核心は、Goコンパイラの構文解析器がimport
ステートメントの誤った形式を検出した際に、より適切なエラーメッセージを生成するように、エラー定義を追加した点にあります。
以前のコンパイラでは、import testing
のような記述があった場合、パーサーはimport
キーワードの後にLNAME
(識別子、この場合はtesting
)が来たことを検出します。しかし、期待されるのはLLITERAL
(文字列リテラル)でした。この不一致により、パーサーは一般的な「unexpected semicolon or newline, expecting string literal
」というエラーを発生させていました。これは、import
の後に文字列リテラルが来ない場合、パーサーが次のトークンをセミコロンや改行と誤解釈し、その後に文字列リテラルが続くことを期待するという、より一般的な構文エラーのパターンに合致していたためです。
このコミットでは、src/cmd/gc/go.errors
に新しいエラーパターンが追加されました。
% loadsys package LIMPORT LNAME ';'
"missing import path; require quoted string",
この行は、以下のような構文パターンを検出した場合に特定のエラーメッセージを出力するようにコンパイラに指示します。
% loadsys package
: これは、Goコンパイラの内部的なエラー定義の構文の一部です。LIMPORT
:import
キーワードを表す字句トークン。LNAME
: 識別子(この場合はtesting
)。';'
: セミコロン。Go言語では、ステートメントの終端にセミコロンを置くことができますが、通常は改行で代用されます。しかし、パーサーの内部的な処理では、このような状況でセミコロンが補完されることがあります。
この新しいパターンは、「import
キーワードの直後に識別子(LNAME
)が来て、その後にセミコロン(または暗黙のセミコロン)が続く」という特定の誤ったimport
構文を正確に捉えます。このパターンに合致した場合、コンパイラは「missing import path; require quoted string
」という、より具体的で分かりやすいエラーメッセージを出力するようになります。
同時に、src/cmd/gc/yerr.h
にも対応するエラーコードとメッセージが追加されました。
32, ';',
"missing import path; require quoted string",
これは、go.errors
で定義された新しいエラーパターンに対応する、コンパイラ内部で使用されるエラーID(32
)と、そのエラーメッセージ文字列を関連付けています。これにより、コンパイラは新しいエラーパターンを検出した際に、この特定のメッセージを正確に参照して出力できるようになります。
この変更により、コンパイラは一般的な構文エラーとして処理するのではなく、import
ステートメントにおける特定の誤用を識別し、その原因を直接的に示すエラーメッセージを提供できるようになりました。これは、コンパイラのエラー診断能力を向上させ、開発者のデバッグ体験を改善する上で重要な改善です。
コアとなるコードの変更箇所
このコミットによるコードの変更は、以下の2つのファイルに集中しています。
-
src/cmd/gc/go.errors
--- a/src/cmd/gc/go.errors +++ b/src/cmd/gc/go.errors @@ -17,6 +17,9 @@ static struct { % loadsys package LIMPORT '(' LLITERAL import_package import_there ',' "unexpected comma during import block", + % loadsys package LIMPORT LNAME ';' + "missing import path; require quoted string", + % loadsys package imports LFUNC LNAME '(' ')' '{' LIF if_header ';' "unexpected semicolon or newline before {",
このファイルに、新しいエラーパターンとそれに対応するエラーメッセージの定義が追加されました。
-
src/cmd/gc/yerr.h
--- a/src/cmd/gc/yerr.h +++ b/src/cmd/gc/yerr.h @@ -17,6 +17,9 @@ static struct { 221, ',', "unexpected comma during import block", + 32, ';', + "missing import path; require quoted string", + 377, ';', "unexpected semicolon or newline before {",
このファイルに、
go.errors
で追加された新しいエラーメッセージに対応する数値コードとメッセージ文字列が追加されました。
コアとなるコードの解説
src/cmd/gc/go.errors
の変更
追加された行:
% loadsys package LIMPORT LNAME ';'
"missing import path; require quoted string",
この行は、Goコンパイラのパーサーが特定の構文パターンを検出したときに、特定のエラーメッセージを生成するためのルールを定義しています。
% loadsys package
: これは、Goコンパイラの内部的なエラー定義の構文の一部であり、パーサーがパッケージレベルの構文エラーを処理する方法に関連しています。LIMPORT
: 字句解析器(lexer)によって識別されるimport
キーワードのトークンです。LNAME
: 字句解析器によって識別される識別子(変数名、関数名など)のトークンです。このコンテキストでは、import testing
のtesting
がこれに該当します。';'
: セミコロンのトークンです。Go言語では、ステートメントの終わりにセミコロンを省略できますが、パーサーは内部的に改行をセミコロンとして解釈(自動セミコロン挿入)することがあります。このパターンは、import LNAME
の後に暗黙的または明示的なセミコロンが続く状況を捉えます。"missing import path; require quoted string"
: 上記のパターンが検出された場合に表示されるエラーメッセージです。このメッセージは、インポートパスが不足しており、引用符で囲まれた文字列が必要であることを明確に示しています。
この追加により、コンパイラはimport
の後に引用符で囲まれていない識別子がある場合に、より的確なエラーメッセージを出力できるようになりました。
src/cmd/gc/yerr.h
の変更
追加された行:
32, ';',
"missing import path; require quoted string",
この行は、C言語のヘッダーファイル形式で、コンパイラ内部で使用されるエラーコードとそれに対応するエラーメッセージを定義しています。
32
: これは、新しく追加されたエラーメッセージに割り当てられた一意の数値IDです。go.errors
で定義されたパターンが検出されると、このIDが参照されます。';'
: このエラーが関連するトークンを示しています。この場合、import LNAME
の後に続くセミコロン(または自動挿入されたセミコロン)がエラーのトリガーとなるトークンの一つであることを示唆しています。"missing import path; require quoted string"
: 実際にユーザーに表示されるエラーメッセージ文字列です。
これらの変更は、Goコンパイラのフロントエンドにおけるエラー診断の精度を向上させ、開発者がGo言語の構文規則をより迅速に理解し、誤りを修正できるようにするためのものです。
関連リンク
- Go Issue #5332: cmd/gc: improve syntax error for "import testing"
- Go CL 9393043: cmd/gc: improve syntax error for "import testing"
参考にした情報源リンク
- Go言語の公式ドキュメント: https://go.dev/doc/
- Goコンパイラのソースコード (特に
src/cmd/gc
ディレクトリ): https://github.com/golang/go/tree/master/src/cmd/gc - Go言語の
import
宣言に関する仕様: https://go.dev/ref/spec#Import_declarations - Yacc/Bisonのようなパーサー生成ツールのエラーハンドリングに関する一般的な情報。
- Go言語の自動セミコロン挿入ルールに関する情報。