...

パッケージ scanner

import "go/scanner"
概要
目次

概要 ▾

scanner パッケージは,Go ソーステキストのスキャナーを実装します。 []byte を読み込み,Scan メソッドに繰り返し適用してトークンに変換します。

func PrintError

func PrintError(w io.Writer, err error)

PrintError は, err パラメータが ErrorList の場合,エラーのリストを 1 行に 1 エラーずつ w に出力するユーティリティ関数です。 そうでなければ,エラー文字列を表示します。

type Error

ErrorList では,エラーは *Error で表されます。 位置 Pos が有効であれば,問題のトークンの先頭を指し,エラー状態は Msg で表されます。

type Error struct {
    Pos token.Position
    Msg string
}

func (Error) Error

func (e Error) Error() string

Error はエラーインターフェースを実装します。

type ErrorHandler

ErrorHandler は Scanner.Init に渡すことができます。 構文エラーが発生してハンドラがインストールされた場合は,そのハンドラが位置とエラーメッセージとともに呼び出されます。 位置は,問題のあるトークンの先頭を指しています。

type ErrorHandler func(pos token.Position, msg string)

type ErrorList

ErrorList は * エラーのリストです。 ErrorList のゼロ値は,使用可能な空の ErrorList です。

type ErrorList []*Error

func (*ErrorList) Add

func (p *ErrorList) Add(pos token.Position, msg string)

Add は与えられた位置とエラーメッセージを持つ Error を ErrorList に追加します。

func (ErrorList) Err

func (p ErrorList) Err() error

Err は,このエラーリストと同等のエラーを返します。 リストが空の場合, Err は nil を返します。

func (ErrorList) Error

func (p ErrorList) Error() string

ErrorList はエラーインターフェースを実装します。

func (ErrorList) Len

func (p ErrorList) Len() int

ErrorList は sort インターフェースを実装します。

func (ErrorList) Less

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

func (*ErrorList) RemoveMultiples

func (p *ErrorList) RemoveMultiples()

RemoveMultiples は ErrorList をソートして, 1 行の最初のエラーを除くすべてのエラーを削除します。

func (*ErrorList) Reset

func (p *ErrorList) Reset()

リセットすると, ErrorList がエラーなしにリセットされます。

func (ErrorList) Sort

func (p ErrorList) Sort()

並べ替えは, ErrorList を並べ替えます。 *Error エントリは位置によってソートされ,他のエラーはエラーメッセージによってソートされます。

func (ErrorList) Swap

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

type Mode

モード値は一連のフラグ (または 0) です。 これらはスキャナの動作を制御します。

type Mode uint
const (
    ScanComments Mode = 1 << iota // COMMENT トークンとしてコメントを返す

)

type Scanner

Scanner (スキャナ) は,与えられたテキストを処理している間,スキャナの内部状態を保持します。 他のデータ構造の一部として割り当てることができますが,使用する前に Init で初期化する必要があります。

type Scanner struct {

    // 公開状態 - 変更しても構いません
    ErrorCount int // 発生したエラー数
    // エクスポートされていないフィールドがあります
}

func (*Scanner) Init

func (s *Scanner) Init(file *token.File, src []byte, err ErrorHandler, mode Mode)

Init は,スキャナ src の先頭にスキャナを設定することによって,テキスト src をトークン化するためにスキャナ s を準備します。 スキャナーは位置情報にファイルセットファイルを使用し,各行に行情報を追加します。 すでに存在する行情報が無視されるので,同じファイルを再スキャンするときに同じファイルを再利用しても構いません。 ファイルサイズが src サイズと一致しない場合, Init はパニックを引き起こします。

Scan を呼び出すと,構文エラーが発生し, err が nil ではない場合,エラーハンドラ err が呼び出されます。 また,発生したエラーごとに, Scanner フィールド ErrorCount が 1 ずつ増加します。 mode パラメータは,コメントの処理方法を決定します。

ファイルの最初の文字にエラーがある場合, Init は err を呼び出すことがあります。

func (*Scanner) Scan

func (s *Scanner) Scan() (pos token.Pos, tok token.Token, lit string)

Scan は次のトークンをスキャンして,トークン位置,トークン,および該当する場合はそのリテラル文字列を返します。 ソースの終わりは token.EOF で示されています。

返されたトークンがリテラル (token.IDENT , token.INT , token.FLOAT , token.IMAG , token.CHAR , token.STRING) または token.COMMENT の場合,リテラル文字列は対応する値を持ちます。

返されたトークンがキーワードの場合,リテラル文字列はキーワードです。

返されたトークンが token.SEMICOLON の場合,対応するリテラル文字列は ";" です。 セミコロンがソースに存在した場合は,改行または EOF のためにセミコロンが挿入された場合は "\n" 。

返されたトークンが token.ILLEGAL の場合,リテラル文字列は問題のある文字です。

それ以外の場合, Scan は空のリテラル文字列を返します。

より寛容な構文解析のために,構文エラーが発生した場合でも,可能であれば Scan は有効なトークンを返します。 したがって,結果のトークンシーケンスに不正なトークンが含まれていなくても,クライアントはエラーが発生していないと見なすことはできません。 代わりに,スキャナの ErrorCount またはエラーハンドラの呼び出し数 (インストールされている場合) を確認する必要があります。

Scan は Init でファイルセットに追加されたファイルに行情報を追加します。 トークン位置はそのファイルに対する相対的なものであり,したがってファイルセットに対する相対的なものです。

コード:

// src はトークン化したい入力です。
src := []byte("cos(x) + 1i*sin(x) // Euler")

// スキャナを初期化します。
var s scanner.Scanner
fset := token.NewFileSet()                      // 位置は fset に対する相対位置です
file := fset.AddFile("", fset.Base(), len(src)) // 入力 "ファイル" を登録
s.Init(file, src, nil /* no error handler */, scanner.ScanComments)

// Scan を繰り返し呼び出すと,入力に含まれるトークンシーケンスが得られます。
for {
    pos, tok, lit := s.Scan()
    if tok == token.EOF {
        break
    }
    fmt.Printf("%s\t%s\t%q\n", fset.Position(pos), tok, lit)
}

出力:

1:1	IDENT	"cos"
1:4	(	""
1:5	IDENT	"x"
1:6	)	""
1:8	+	""
1:10	IMAG	"1i"
1:12	*	""
1:13	IDENT	"sin"
1:16	(	""
1:17	IDENT	"x"
1:18	)	""
1:20	;	"\n"
1:20	COMMENT	"// Euler"