Spec-Zone.ru › Go

Пакет scanner

  • import "text/scanner"
  • Обзор
  • Указатель
  • Примеры

Обзор

Пакет scanner предоставляет сканер и токенизатор для текста в кодировке UTF-8. Он принимает io.Reader, предоставляющий источник, который затем можно токенизировать повторными вызовами функции Scan. Для совместимости с существующими инструментами символ NUL не допускается. Если первый символ в источнике — метка порядка байтов (BOM), закодированная в UTF-8, она отбрасывается.

По умолчанию Scanner пропускает пробельные символы и комментарии Go и распознаёт все литералы, определённые спецификацией языка Go. Его можно настроить так, чтобы он распознавал только подмножество этих литералов, а также другие символы идентификаторов и пробельные символы.

Пример

Код:

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())
}

Вывод:

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: }

Пример (IsIdentRune)

Код:

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"

// treat leading '%' as part of an identifier
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())
}

Вывод:

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: %

Пример (Mode)

Код:

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 // don't skip comments

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)
    }
}

Вывод:

comments:2:5: // Comment begins at column 5.
comments:6:1: /*
This multiline comment
should be extracted in
its entirety.
*/

Пример (Whitespace)

Код:

// 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 // large enough for example above
)
s.Init(strings.NewReader(src))
s.Whitespace ^= 1<<'\t' | 1<<'\n' // don't skip tabs and new lines

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)

Вывод:

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

Указатель

  • Константы
  • func TokenString(tok rune) string
  • type Position
  • func (pos *Position) IsValid() bool
  • func (pos Position) String() string
  • type Scanner
  • func (s *Scanner) Init(src io.Reader) *Scanner
  • func (s *Scanner) Next() rune
  • func (s *Scanner) Peek() rune
  • func (s *Scanner) Pos() (pos Position)
  • func (s *Scanner) Scan() rune
  • func (s *Scanner) TokenText() string

Примеры

Пакет
Пакет (IsIdentRune)
Пакет (Mode)
Пакет (Whitespace)

Файлы пакета

scanner.go

Константы

Предопределённые биты режима для управления распознаванием токенов. Например, чтобы настроить Scanner так, чтобы он распознавал только идентификаторы Go и целые числа, а также пропускал комментарии, установите поле Mode сканера в значение:

ScanIdents | ScanInts | ScanComments | SkipComments

За исключением комментариев, которые пропускаются, если установлен SkipComments, нераспознанные токены не игнорируются. Вместо этого сканер просто возвращает соответствующие отдельные символы (или, возможно, под-токены). Например, если режим — ScanIdents (а не ScanStrings), строка "foo" сканируется как последовательность токенов '"' Ident '"'.

Используйте GoTokens, чтобы настроить Scanner на приём всех токенов литералов Go, включая идентификаторы Go. Комментарии будут пропускаться.

const (
    ScanIdents     = 1 << -Ident
    ScanInts       = 1 << -Int
    ScanFloats     = 1 << -Float // includes Ints and hexadecimal floats
    ScanChars      = 1 << -Char
    ScanStrings    = 1 << -String
    ScanRawStrings = 1 << -RawString
    ScanComments   = 1 << -Comment
    SkipComments   = 1 << -skipComment // if set with ScanComments, comments become white space
    GoTokens       = ScanIdents | ScanFloats | ScanChars | ScanStrings | ScanRawStrings | ScanComments | SkipComments
)

Результатом Scan является один из этих токенов или символ Unicode.

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

GoWhitespace — значение по умолчанию для поля Whitespace у Scanner. Это значение выбирает пробельные символы Go.

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

func TokenString

func TokenString(tok rune) string

TokenString возвращает строку для отображения токена или символа Unicode.

type Position

Position — это значение, представляющее позицию в исходном тексте. Позиция допустима, если Line > 0.

type Position struct {
    Filename string // filename, if any
    Offset   int    // byte offset, starting at 0
    Line     int    // line number, starting at 1
    Column   int    // column number, starting at 1 (character count per line)
}

func (*Position) IsValid

func (pos *Position) IsValid() bool

IsValid сообщает, является ли позиция допустимой.

func (Position) String

func (pos Position) String() string

type Scanner

Scanner реализует чтение символов Unicode и токенов из io.Reader.

type Scanner struct {

    // Error is called for each error encountered. If no Error
    // function is set, the error is reported to os.Stderr.
    Error func(s *Scanner, msg string)

    // ErrorCount is incremented by one for each error encountered.
    ErrorCount int

    // The Mode field controls which tokens are recognized. For instance,
    // to recognize Ints, set the ScanInts bit in Mode. The field may be
    // changed at any time.
    Mode uint

    // The Whitespace field controls which characters are recognized
    // as white space. To recognize a character ch <= ' ' as white space,
    // set the ch'th bit in Whitespace (the Scanner's behavior is undefined
    // for values ch > ' '). The field may be changed at any time.
    Whitespace uint64

    // IsIdentRune is a predicate controlling the characters accepted
    // as the ith rune in an identifier. The set of valid characters
    // must not intersect with the set of white space characters.
    // If no IsIdentRune function is set, regular Go identifiers are
    // accepted instead. The field may be changed at any time.
    IsIdentRune func(ch rune, i int) bool // Go 1.4

    // Start position of most recently scanned token; set by Scan.
    // Calling Init or Next invalidates the position (Line == 0).
    // The Filename field is always left untouched by the Scanner.
    // If an error is reported (via Error) and Position is invalid,
    // the scanner is not inside a token. Call Pos to obtain an error
    // position in that case, or to obtain the position immediately
    // after the most recently scanned token.
    Position
    // contains filtered or unexported fields
}

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; в противном случае выводит сообщение об ошибке в 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.Position].

func (*Scanner) Scan

func (s *Scanner) Scan() rune

Scan читает и возвращает следующий токен или символ Unicode из источника. Он распознаёт только те токены t, для которых установлен соответствующий бит Scanner.Mode (1<<-t). В конце источника возвращает EOF. Об ошибках сканера (ошибках чтения и токенов) сообщает, вызывая s.Error, если она не равна nil; в противном случае выводит сообщение об ошибке в os.Stderr.

func (*Scanner) TokenText

func (s *Scanner) TokenText() string

TokenText возвращает строку, соответствующую последнему просканированному токену. Доступен после вызова Scanner.Scan и при вызовах Scanner.Error.

© Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
http://golang.org/pkg/text/scanner/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API