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 ¶
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リテラルトークンが受け入れられます。 コメントはスキップされます。
const ( EOF = -(iota + 1) Ident Int Float Char String RawString Comment )
Scanの結果は、これらのトークンのいずれか、またはUnicode文字です。
const GoWhitespace = 1<<'\t' | 1<<'\n' | 1<<'\r' | 1<<' '
GoWhitespaceは、Scanner のWhitespaceフィールドのデフォルト値です。 その値はGoの空白文字を選択します。
Variables ¶
This section is empty.
Functions ¶
Types ¶
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 ¶
Initは新しいソースで Scanner を初期化し、sを返します。 [Scanner.Error] はnilに設定され、[Scanner.ErrorCount] は0に設定され、[Scanner.Mode] は GoTokens に設定され、 [Scanner.Whitespace] は GoWhitespace に設定されます。
func (*Scanner) Next ¶
Nextは次のUnicode文字を読み取り、返します。 ソースの終わりで EOF を返します。読み取りエラーが発生した場合、 s.Errorがnilでない場合はs.Errorを呼び出して報告します。それ以外の場合は os.Stderr にエラーメッセージを出力します。Nextは [Scanner.Position] フィールドを 更新しません。現在の位置を取得するには、Scanner.Pos()を使用します。
func (*Scanner) Pos ¶
Posは、最後の Scanner.Next または Scanner.Scan の呼び出しによって返された文字またはトークンの直後の文字の位置を返します。 最近スキャンされたトークンの開始位置には、Scannerの [Scanner.Position] フィールドを使用します。
func (*Scanner) Scan ¶
Scanは、ソースから次のトークンまたはUnicode文字を読み取り、それを返します。 それは、それぞれの [Scanner.Mode] ビット(1<<-t)が設定されているトークンtのみを認識します。 ソースの終わりで EOF を返します。スキャナのエラー(読み取りエラーとトークンエラー)は、 s.Errorがnilでない場合にはs.Errorを呼び出すことで報告します。それ以外の場合は、 os.Stderr にエラーメッセージを出力します。
func (*Scanner) TokenText ¶
TokenTextは、最近スキャンされたトークンに対応する文字列を返します。 Scanner.Scan の呼び出し後、および [Scanner.Error] の呼び出し中に有効です。