import "go/scanner"

Go言語のソーステキスト用のスキャナです。Scan関数を繰り返し呼び出して、ソースとして受け取った[]byteをトークン化します。下は、一般的な使用方法です。

var s Scanner
     fset := token.NewFileSet()  // 位置情報は、fsetからの相対
	s.Init(fset, filename, src, nil /* エラーは扱わない */, 0)
     for {
		pos, tok, lit := s.Scan()
		if tok == token.EOF {
			break
		}
		// pos, tok, litを使って何か行う
	}

パッケージファイル

errors.go scanner.go

定数

Init関数のmodeパラメータには、フラグの組み合わせ(または0)を渡します。これらはスキャナの動作を制御します。

const (
    ScanComments      = 1 << iota // コメントをCOMMENTトークンとして返す
    AllowIllegalChars             // 不正な文字をエラーとして報告しない
    InsertSemis                   // セミコロンの自動挿入
)

これらの定数は、GetErrorsによって返されるErrorListの作成を制御します。

const (
    Raw         = iota // エラーリストに何も手を加えない
    Sorted             // エラーリストを、ファイル、行、カラム番号でソートする
    NoMultiples        // エラーリストとをソートするが、各行の最初のエラーだけを含める
)

PrintError関数

func PrintError(w io.Writer, err os.Error)

PrintErrorは、wにエラーリストを出力するためのユーティリティ関数です。errパラメータにErrorListを渡したときは、その中のエラーをそれぞれ一行として出力し、それ以外を渡したときは、エラー文字列を出力します。

Error型

ErrorVectorにおいて、エラーの一つ一つはErrorノードによって表されます。位置Posが有効なときは問題のあったトークンの開始点を指し、またエラー状況はMsgに格納されます。

type Error struct {
    Pos token.Position
    Msg string
}

(*Error) String関数

func (e *Error) String() string

ErrorHandler型

ErrorHandlerの実装は、Scannerに渡されます。ハンドラがインストールされていると、構文エラーがあったときに、そのエラー位置とエラーメッセージをパラメータとしてErrorメソッドが呼び出されます。この位置は、問題のあったトークンの開始位置を指し示します。

type ErrorHandler interface {
    Error(pos token.Position, msg string)
}

ErrorList型

ErrorListは、エラーのリスト(可能であればソート済み)です。

type ErrorList []*Error

(ErrorList) Len関数

func (p ErrorList) Len() int

ErrorListは、sortパッケージのInterfaceを実装しています。

(ErrorList) Less関数

func (p ErrorList) Less(i, j int) bool

(ErrorList) String関数

func (p ErrorList) String() string

(ErrorList) Swap関数

func (p ErrorList) Swap(i, j int)

ErrorVector型

ErrorVectorは、ErrorHandlerインタフェースを実装しています。この型では、エラーのリストを管理しており、これはGetErrorListまたはGetErrorで取り出せます。ErrorVectorのゼロ値は、利用可能かつ空のErrorVectorです。

一般的な使用パターンとしては、Scannerを使用するデータ構造内に、Scannerと一緒にErrorVectorを埋め込みます。ScannerのInitを呼び出すときに、ErrorVectorへの参照を渡すことで、デフォルトのエラー処理を担わせることができます。

type ErrorVector struct {
    // contains unexported fields
}

(*ErrorVector) Error関数

func (h *ErrorVector) Error(pos token.Position, msg string)

ErrorVectorは、ErrorHandlerインタフェースを実装しています。

(*ErrorVector) ErrorCount関数

func (h *ErrorVector) ErrorCount() int

ErrorCountは、収集したエラー件数を返します。

(*ErrorVector) GetError関数

func (h *ErrorVector) GetError(mode int) os.Error

GetErrorは、GetErrorListとほぼ同じですが、os.Errorを返すので、エラーが無くともnilの代わりにos.Errorとして値を返すことができます。

(*ErrorVector) GetErrorList関数

func (h *ErrorVector) GetErrorList(mode int) ErrorList

GetErrorListは、ErrorVectorによって収集したエラーのリストを返します。返却値のErrorListを作成する際に、modeパラメータを使って制御します。エラーがなかったときは、nilが返ります。

(*ErrorVector) Reset関数

func (h *ErrorVector) Reset()

Resetは、ErrorVectorをリセットしてエラーの無い状態にします。

Scanner型

Scannerは、テキストを処理している間、スキャナの内部状態を保持し続けます。この型は他のデータ構造の一部として割り当てることもできますが、使用する前にInitで初期化しなければなりません。

type Scanner struct {

    // public state - ok to modify
    ErrorCount int // 発生したエラー件数
    // contains unexported fields
}

(*Scanner) Init関数

func (S *Scanner) Init(fset *token.FileSet, filename string, src []byte, err ErrorHandler, mode uint) *token.File

Initは、テキストsrcをトークン化するためにスキャナSの準備を整えます。これは、ソーステキストの先頭をスキャナにセットし、ファイルセットfsetに、filenameとして与えたファイルを新たに加え、そのファイルを返します。

Scanを呼び出したときに、文法エラーが見つかり、かつerrがnilのときは、errがエラーハンドラとして使用されます。エラーが起きる度に、ScannerのErrorCountフィールドがひとつインクリメントされます。modeパラメータは、コメントと不正な文字とセミコロンの扱い方を取り決めます。

(*Scanner) Scan関数

func (S *Scanner) Scan() (token.Pos, token.Token, []byte)

Scanは、次のトークンをスキャンし、トークンの位置pos、トークンtok、トークンが表すテキストlitを返します。ソースの終りに達したことはtoken.EOFによって検知できます。

返されたトークンがtoken.SEMICOLONのとき、それに対応するリテラルの値は、ソース内にセミコロンが現れたときは「;」、改行またはEOFによってセミコロンが挿入されたときは「\n」です。

パースの際に、なるべくエラーとしないように、構文エラーがあったとしても、可能な限り有効なトークンを戻り値として返します。そのためクライアントは、たとえ返された一連のトークン内に不正なトークンが含まれていなかったとしても、エラーが発生しなかったと仮定すべきではありません。代わりに、ScannerのErrorCountをチェックするか、エラーハンドラが登録されていれば、そのハンドラが呼び出された回数をチェックしてください。

Scanは、Initでファイルセットに追加したファイルに対し、行情報を加えます。トークンの位置は、ファイルからの相対であり、ゆえにファイルセットからの相対でもあります。