scanner

package
v1.25.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 5, 2025 License: MIT Imports: 2 Imported by: 0

Documentation

Overview

scannerパッケージは、UTF-8エンコードされたテキストのスキャナとトークナイザを提供します。 それはソースを提供するio.Readerを取り、その後、Scan関数を繰り返し呼び出すことでトークン化できます。 既存のツールとの互換性のため、NUL文字は許可されていません。ソースの最初の文字が UTF-8エンコードされたバイトオーダーマーク(BOM)である場合、それは破棄されます。

デフォルトでは、Scanner は空白とGoのコメントをスキップし、Go言語仕様によって定義されたすべての リテラルを認識します。それは、それらのリテラルの一部のみを認識し、異なる識別子と空白文字を認識するように カスタマイズすることができます。

Example
package main

import (
	"github.com/shogo82148/std/fmt"
	"github.com/shogo82148/std/strings"
	"github.com/shogo82148/std/text/scanner"
)

func main() {
	const src = `
// This is scanned code.
if a > 10 {
	someParsable = text
}`

	var s scanner.Scanner
	s.Init(strings.NewReader(src))
	s.Filename = "example"
	for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() {
		fmt.Printf("%s: %s\n", s.Position, s.TokenText())
	}

}
Output:

example:3:1: if
example:3:4: a
example:3:6: >
example:3:8: 10
example:3:11: {
example:4:2: someParsable
example:4:15: =
example:4:17: text
example:5:1: }
Example (IsIdentRune)
package main

import (
	"github.com/shogo82148/std/fmt"
	"github.com/shogo82148/std/strings"
	"github.com/shogo82148/std/text/scanner"
	"github.com/shogo82148/std/unicode"
)

func main() {
	const src = "%var1 var2%"

	var s scanner.Scanner
	s.Init(strings.NewReader(src))
	s.Filename = "default"

	for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() {
		fmt.Printf("%s: %s\n", s.Position, s.TokenText())
	}

	fmt.Println()
	s.Init(strings.NewReader(src))
	s.Filename = "percent"

	// 先頭の '%' を識別子の一部として扱う
	s.IsIdentRune = func(ch rune, i int) bool {
		return ch == '%' && i == 0 || unicode.IsLetter(ch) || unicode.IsDigit(ch) && i > 0
	}

	for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() {
		fmt.Printf("%s: %s\n", s.Position, s.TokenText())
	}

}
Output:

default:1:1: %
default:1:2: var1
default:1:7: var2
default:1:11: %

percent:1:1: %var1
percent:1:7: var2
percent:1:11: %
Example (Mode)
package main

import (
	"github.com/shogo82148/std/fmt"
	"github.com/shogo82148/std/strings"
	"github.com/shogo82148/std/text/scanner"
)

func main() {
	const src = `
    // Comment begins at column 5.

This line should not be included in the output.

/*
This multiline comment
should be extracted in
its entirety.
*/
`

	var s scanner.Scanner
	s.Init(strings.NewReader(src))
	s.Filename = "comments"
	s.Mode ^= scanner.SkipComments // コメントをスキップしない

	for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() {
		txt := s.TokenText()
		if strings.HasPrefix(txt, "//") || strings.HasPrefix(txt, "/*") {
			fmt.Printf("%s: %s\n", s.Position, txt)
		}
	}

}
Output:

comments:2:5: // Comment begins at column 5.
comments:6:1: /*
This multiline comment
should be extracted in
its entirety.
*/
Example (Whitespace)
package main

import (
	"github.com/shogo82148/std/fmt"
	"github.com/shogo82148/std/strings"
	"github.com/shogo82148/std/text/scanner"
)

func main() {
	// tab-separated values
	const src = `aa	ab	ac	ad
ba	bb	bc	bd
ca	cb	cc	cd
da	db	dc	dd`

	var (
		col, row int
		s        scanner.Scanner
		tsv      [4][4]string // 上記の例に十分な大きさ
	)
	s.Init(strings.NewReader(src))
	s.Whitespace ^= 1<<'\t' | 1<<'\n' // タブと改行をスキップしない

	for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() {
		switch tok {
		case '\n':
			row++
			col = 0
		case '\t':
			col++
		default:
			tsv[row][col] = s.TokenText()
		}
	}

	fmt.Print(tsv)

}
Output:

[[aa ab ac ad] [ba bb bc bd] [ca cb cc cd] [da db dc dd]]

Index

Examples

Constants

View Source
const (
	ScanIdents     = 1 << -Ident
	ScanInts       = 1 << -Int
	ScanFloats     = 1 << -Float
	ScanChars      = 1 << -Char
	ScanStrings    = 1 << -String
	ScanRawStrings = 1 << -RawString
	ScanComments   = 1 << -Comment
	SkipComments   = 1 << -skipComment
	GoTokens       = ScanIdents | ScanFloats | ScanChars | ScanStrings | ScanRawStrings | ScanComments | SkipComments
)

トークンの認識を制御するための事前定義されたモードビット。 例えば、(Goの)識別子と整数のみを認識し、コメントをスキップするように Scanner を設定するには、ScannerのModeフィールドを次のように設定します:

ScanIdents | ScanInts | ScanComments | SkipComments

SkipCommentsが設定されている場合、コメントはスキップされるを除いて、 認識されないトークンは無視されません。代わりに、スキャナは単に それぞれの個々の文字(または可能性のあるサブトークン)を返します。 例えば、モードがScanIdents(ScanStringsではない)の場合、文字列 "foo"はトークンシーケンス '"' Ident '"'としてスキャンされます。

GoTokensを使用してScannerを設定すると、Goの識別子を含むすべてのGoリテラルトークンが受け入れられます。 コメントはスキップされます。

View Source
const (
	EOF = -(iota + 1)
	Ident
	Int
	Float
	Char
	String
	RawString
	Comment
)

Scanの結果は、これらのトークンのいずれか、またはUnicode文字です。

View Source
const GoWhitespace = 1<<'\t' | 1<<'\n' | 1<<'\r' | 1<<' '

GoWhitespaceは、Scanner のWhitespaceフィールドのデフォルト値です。 その値はGoの空白文字を選択します。

Variables

This section is empty.

Functions

func TokenString

func TokenString(tok rune) string

TokenStringは、トークンまたはUnicode文字の印刷可能な文字列を返します。

Types

type Position

type Position struct {
	Filename string
	Offset   int
	Line     int
	Column   int
}

Positionはソース位置を表す値です。 Line > 0 の場合、位置は有効です。

func (*Position) IsValid

func (pos *Position) IsValid() bool

IsValidは位置が有効かどうかを報告します。

func (Position) String

func (pos Position) String() string

type Scanner

type Scanner struct {

	// Errorは、発生した各エラーに対して呼び出されます。Error
	// 関数が設定されていない場合、エラーはos.Stderrに報告されます。
	Error func(s *Scanner, msg string)

	// ErrorCountは、発生した各エラーごとに1ずつ増加します。
	ErrorCount int

	// Modeフィールドは、どのトークンが認識されるかを制御します。例えば、
	// Intsを認識するには、ModeのScanIntsビットを設定します。このフィールドは
	// いつでも変更することができます。
	Mode uint

	// Whitespaceフィールドは、どの文字が空白として認識されるかを制御します。
	// 文字ch <= ' 'を空白として認識するには、Whitespaceのch番目のビットを設定します
	// (ch > ' 'の値に対するScannerの挙動は未定義です)。このフィールドはいつでも変更できます。
	Whitespace uint64

	// IsIdentRuneは、識別子のithルーンとして受け入れられる文字を制御する述語です。
	// 有効な文字のセットは、空白文字のセットと交差してはなりません。
	// IsIdentRune関数が設定されていない場合、代わりに通常のGoの識別子が受け入れられます。
	// このフィールドはいつでも変更することができます。
	IsIdentRune func(ch rune, i int) bool

	// 最近スキャンされたトークンの開始位置。Scanによって設定されます。
	// InitまたはNextを呼び出すと、位置が無効になります(Line == 0)。
	// Filenameフィールドは常にScannerによって untouched のままです。
	// エラーが報告され(Error経由で)かつPositionが無効な場合、
	// スキャナはトークンの内部にはありません。その場合、または最近スキャンされたトークンの
	// 直後の位置を取得するには、Posを呼び出します。
	Position
	// contains filtered or unexported fields
}

Scannerは、io.ReaderからのUnicode文字とトークンの読み取りを実装します。

func (*Scanner) Init

func (s *Scanner) Init(src io.Reader) *Scanner

Initは新しいソースで Scanner を初期化し、sを返します。 [Scanner.Error] はnilに設定され、[Scanner.ErrorCount] は0に設定され、[Scanner.Mode] は GoTokens に設定され、 [Scanner.Whitespace] は GoWhitespace に設定されます。

func (*Scanner) Next

func (s *Scanner) Next() rune

Nextは次のUnicode文字を読み取り、返します。 ソースの終わりで EOF を返します。読み取りエラーが発生した場合、 s.Errorがnilでない場合はs.Errorを呼び出して報告します。それ以外の場合は os.Stderr にエラーメッセージを出力します。Nextは [Scanner.Position] フィールドを 更新しません。現在の位置を取得するには、Scanner.Pos()を使用します。

func (*Scanner) Peek

func (s *Scanner) Peek() rune

Peekは、スキャナを進めずにソースの次のUnicode文字を返します。 スキャナの位置がソースの最後の文字にある場合、EOF を返します。

func (*Scanner) Pos

func (s *Scanner) Pos() (pos Position)

Posは、最後の Scanner.Next または Scanner.Scan の呼び出しによって返された文字またはトークンの直後の文字の位置を返します。 最近スキャンされたトークンの開始位置には、Scannerの [Scanner.Position] フィールドを使用します。

func (*Scanner) Scan

func (s *Scanner) Scan() rune

Scanは、ソースから次のトークンまたはUnicode文字を読み取り、それを返します。 それは、それぞれの [Scanner.Mode] ビット(1<<-t)が設定されているトークンtのみを認識します。 ソースの終わりで EOF を返します。スキャナのエラー(読み取りエラーとトークンエラー)は、 s.Errorがnilでない場合にはs.Errorを呼び出すことで報告します。それ以外の場合は、 os.Stderr にエラーメッセージを出力します。

func (*Scanner) TokenText

func (s *Scanner) TokenText() string

TokenTextは、最近スキャンされたトークンに対応する文字列を返します。 Scanner.Scan の呼び出し後、および [Scanner.Error] の呼び出し中に有効です。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL