首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

go/scanner(扫描仪)

  • import "go/scanner"
  • 概述
  • 索引
  • 示例

概述

Package scanner 为 Go 源文本实现扫描器。它需要一个 []byte 作为源,然后可以通过重复调用 Scan 方法来进行标记。

索引

  • func PrintError(w io.Writer, err error)
  • type Error
  • func (e Error) Error() string
  • type ErrorHandler
  • type ErrorList
  • func (p *ErrorList) Add(pos token.Position, msg string)
  • func (p ErrorList) Err() error
  • func (p ErrorList) Error() string
  • func (p ErrorList) Len() int
  • func (p ErrorList) Less(i, j int) bool
  • func (p *ErrorList) RemoveMultiples()
  • func (p *ErrorList) Reset()
  • func (p ErrorList) Sort()
  • func (p ErrorList) Swap(i, j int)
  • type Mode
  • type Scanner
  • func (s *Scanner) Init(file *token.File, src []byte, err ErrorHandler, mode Mode)
  • func (s *Scanner) Scan() (pos token.Pos, tok token.Token, lit string)

示例

Scanner.Scan

包文件

func PrintError(显示源代码)

代码语言:javascript
复制
func PrintError(w io.Writer, err error)

PrintError 是一个实用程序函数,如果 err 参数是 ErrorList,则会向 w 打印一个错误列表,每行一个错误。否则,它会打印错误字符串。

在 ErrorList 中,错误由 *Error 表示。Pos 位置(如果有效)指向有问题的令牌的开始,错误情况由 Msg 描述。

代码语言:javascript
复制
type Error struct {
        Pos token.Position
        Msg string
}

func (Error) Error(显示源代码)

代码语言:javascript
复制
func (e Error) Error() string

Error 实现了错误接口。

type ErrorHandler(显示源代码)

一个 ErrorHandler 可以提供给 Scanner.Init。如果遇到语法错误并且安装了处理程序,则会使用位置和错误消息调用处理程序。位置指向违规令牌的开始。

代码语言:javascript
复制
type ErrorHandler func(pos token.Position, msg string)

type ErrorList(显示源代码)

ErrorList 是 *Errors 的列表。ErrorList 的零值是一个空的 ErrorList,可以使用。

代码语言:javascript
复制
type ErrorList []*Error

func (*ErrorList) Add(显示源代码)

代码语言:javascript
复制
func (p *ErrorList) Add(pos token.Position, msg string)

Add 添加一个给定位置和错误消息的错误到一个 ErrorList。

func (ErrorList) Err(显示源代码)

代码语言:javascript
复制
func (p ErrorList) Err() error

Err 返回等同于此错误列表的错误。如果列表为空,则 Err 返回 nil。

func (ErrorList) Error(显示源代码)

代码语言:javascript
复制
func (p ErrorList) Error() string

ErrorList 实现错误接口。

func (ErrorList) Len(显示源代码)

代码语言:javascript
复制
func (p ErrorList) Len() int

ErrorList 实现排序接口。

func (ErrorList) Less(显示源代码)

代码语言:javascript
复制
func (p ErrorList) Less(i, j int) bool

func (*ErrorList) RemoveMultiples(显示源代码)

代码语言:javascript
复制
func (p *ErrorList) RemoveMultiples()

RemoveMultiples 对一个 ErrorList 进行排序并删除每行的第一个错误。

func (*ErrorList) Reset(显示源代码)

代码语言:javascript
复制
func (p *ErrorList) Reset()

Reset 将错误列表重置为无错误。

func (ErrorList) Sort(显示源代码)

代码语言:javascript
复制
func (p ErrorList) Sort()

Sort 排序错误列表。*Error 条目按位置排序,其他错误按错误消息排序,并且在任何 *Error 条目之前。

func (ErrorList) Swap(显示源代码)

代码语言:javascript
复制
func (p ErrorList) Swap(i, j int)

mode值是一组标志(或0)。他们控制扫描仪行为。

代码语言:javascript
复制
type Mode uint
代码语言:javascript
复制
const (
        ScanComments Mode = 1 << iota // return comments as COMMENT tokens

)

Scanner 在处理给定文本时保存扫描仪的内部状态。它可以作为另一个数据结构的一部分进行分配,但必须在使用前通过 Init 进行初始化。

代码语言:txt
复制
type Scanner struct {

        // 公共状态 - 可以修改
        ErrorCount int // 遇到的错误数量
        // 包含已过滤或未导出的字段
}

func (*Scanner) Init(显示源代码)

代码语言:javascript
复制
func (s *Scanner) Init(file *token.File, src []byte, err ErrorHandler, mode Mode)

Init 通过将扫描器设置为 src 的开头来准备扫描器来标记文本 src。扫描仪使用文件集文件获取位置信息,并为每行添加行信息。当重新扫描相同的文件时,重新使用同一文件是可以的,因为已经存在的行信息将被忽略。如果文件大小与 src 大小不匹配,则 Init 会导致混乱。

如果遇到语法错误并且 err 不为零,则调用扫描将调用错误处理程序 err。此外,对于遇到的每个错误,扫描器字段 ErrorCount 都会加1。模式参数决定如何处理注释。

请注意,如果文件的第一个字符有错误,Init 可能会调用 err。

func (*Scanner) Scan(显示源代码)

代码语言:javascript
复制
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,则相应的文字字符串是“;” 如果分号存在于源中,则“\n”如果由于换行符或 EOF 而插入了分号。

如果返回的标记是 token.ILLEGAL,则文字字符串是违规字符。

在其他所有情况下,Scan 会返回一个空的文字字符串。

对于更宽容的解析,如果可能,即使遇到语法错误,Scan 也会返回有效的令牌。因此,即使生成的令牌序列不包含非法令牌,客户端也不能认为没有发生错误。相反,它必须检查扫描器的 ErrorCount 或错误处理程序的调用次数,如果安装了一个。

Scan 行信息添加到添加到 Init 文件集的文件中。令牌位置与该文件相关,因此与文件集有关。

示例

代码语言:txt
复制
package main

import (
	"fmt"
	"go/scanner"
	"go/token"
)

func main() {
	// src是我们想要标记化的输入。
	src := []byte("cos(x) + 1i*sin(x) // Euler")

	// 初始化扫描仪。
	var s scanner.Scanner
	fset := token.NewFileSet()                      // positions相对于fset
	file := fset.AddFile("", fset.Base(), len(src)) // 注册输入“file”
	s.Init(file, src, nil /* 没有错误处理程序 */, 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)
	}

}

扫码关注腾讯云开发者

领取腾讯云代金券