tokenizer

package module
v1.5.1 Latest Latest
Warning

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

Go to latest
Published: Jul 17, 2026 License: MIT Imports: 12 Imported by: 12

README

Tokenizer

Build Status codecov Go Report Card GoDoc

High-performance, generic tokenizer (lexer) for Go. It parses any string, byte slice or infinite io.Reader stream into a stream of typed tokens. Use it as the foundation for higher-level parsers and DSLs.

Features

  • Fast. Single pass over the data, zero allocations per token on the hot path (token values point directly into the source buffer — no copies), lookup tables instead of regexp.
  • Simple API.
  • Recognizes integer and float numbers.
  • Recognizes quoted (framed) strings with escaping and embedded injections.
  • User-defined tokens (operators, punctuation, keywords).
  • Unicode-aware keywords.
  • Configurable whitespace symbols.
  • Streams infinite input without loading it fully into memory and without panicking.

Use cases

  • Parsing text formats: XML, HTML, JSON, YAML, etc.
  • Parsing huge or infinite inputs.
  • Parsing programming languages, DSLs, templates and formulas.

Installation

go get github.com/bzick/tokenizer

Table of contents

Quick start

For example, parsing the SQL WHERE condition user_id = 119 and modified > "2020-01-01 00:00:00" or amount >= 122.34:

import "github.com/bzick/tokenizer"

// define keys for the custom tokens
const (
	TEquality = iota + 1
	TDot
	TMath
	TDoubleQuoted
)

// configure the tokenizer
parser := tokenizer.New()
parser.DefineTokens(TEquality, []string{"<", "<=", "==", ">=", ">", "!="})
parser.DefineTokens(TDot, []string{"."})
parser.DefineTokens(TMath, []string{"+", "-", "/", "*", "%"})
parser.DefineStringToken(TDoubleQuoted, `"`, `"`).SetEscapeSymbol(tokenizer.BackSlash)
parser.AllowKeywordSymbols(tokenizer.Underscore, tokenizer.Numbers)

// create the token stream
stream := parser.ParseString(`user_id = 119 and modified > "2020-01-01 00:00:00" or amount >= 122.34`)
defer stream.Close()

// iterate over the tokens
for stream.IsValid() {
	if stream.CurrentToken().Is(tokenizer.TokenKeyword) {
		field := stream.CurrentToken().ValueString()
		// ...
		_ = field
	}
	stream.GoNext()
}

The stream of tokens:

string:  user_id  =  119  and  modified  >  "2020-01-01 00:00:00"  or  amount  >=  122.34
tokens: |user_id| =| 119| and| modified| >| "2020-01-01 00:00:00"| or| amount| >=| 122.34|
        |   0   | 1|  2 |  3 |    4     | 5|          6           | 7|    8  | 9 |   10  |

 0: {key: TokenKeyword, value: "user_id"}                 token.ValueString()          == "user_id"
 1: {key: TEquality,    value: "="}                       token.ValueString()          == "="
 2: {key: TokenInteger, value: "119"}                     token.ValueInt64()           == 119
 3: {key: TokenKeyword, value: "and"}                     token.ValueString()          == "and"
 4: {key: TokenKeyword, value: "modified"}                token.ValueString()          == "modified"
 5: {key: TEquality,    value: ">"}                       token.ValueString()          == ">"
 6: {key: TokenString,  value: "\"2020-01-01 00:00:00\""} token.ValueUnescapedString() == "2020-01-01 00:00:00"
 7: {key: TokenKeyword, value: "or"}                      token.ValueString()          == "or"
 8: {key: TokenKeyword, value: "amount"}                  token.ValueString()          == "amount"
 9: {key: TEquality,    value: ">="}                      token.ValueString()          == ">="
10: {key: TokenFloat,   value: "122.34"}                  token.ValueFloat64()         == 122.34

More examples:

Getting started

Create and parse
import "github.com/bzick/tokenizer"

parser := tokenizer.New()
parser.AllowKeywordSymbols(tokenizer.Underscore, tokenizer.Numbers)
// ... and any other configuration

There are two ways to parse a string or a byte slice. Both return a *Stream:

  • parser.ParseString(str)
  • parser.ParseBytes(slice)

Always Close() the stream when you are done — it releases token objects back to the internal pool:

stream := parser.ParseString(`user_id = 119`)
defer stream.Close()
Parse an infinite stream

The tokenizer can also parse an endless stream of data. Pass an io.Reader and a buffer size (in bytes); data is read and parsed chunk by chunk, so the whole input never needs to fit in memory:

fp, err := os.Open("data.json") // huge JSON file
// handle err, configure the tokenizer ...

stream := parser.ParseStream(fp, 4096).SetHistorySize(10)
defer stream.Close()
for stream.IsValid() {
	// ...
	stream.GoNext()
}

In stream mode only a window of tokens is kept in memory. SetHistorySize(n) controls how many already-visited tokens remain available behind the current one (for GoPrev, GoTo, GetSnippet, etc.).

Built-in tokens

Every token carries one of these built-in keys unless it matches a user-defined token:

  • tokenizer.TokenUnknown — a symbol that does not match any known token.
  • tokenizer.TokenKeyword — a word: any combination of letters, including unicode letters.
  • tokenizer.TokenInteger — an integer number.
  • tokenizer.TokenFloat — a float/double number.
  • tokenizer.TokenString — a quoted (framed) string.
  • tokenizer.TokenStringFragment — a fragment of a framed string that contains injections.
  • tokenizer.TokenUndef — returned when the stream pointer is out of range (see Stream API).
Unknown token

A token is marked as tokenizer.TokenUnknown when the parser encounters a symbol that does not match any known token:

stream := parser.ParseString(`one!`)
stream: [
    {Key: tokenizer.TokenKeyword, Value: "one"},
    {Key: tokenizer.TokenUnknown, Value: "!"},
]

By default, TokenUnknown tokens are added to the stream. Calling parser.StopOnUndefinedToken() makes the parser stop as soon as an unknown token appears:

parser.StopOnUndefinedToken()
stream := parser.ParseString(`one!`)
stream: [
    {Key: tokenizer.TokenKeyword, Value: "one"},
]

Note that with StopOnUndefinedToken() enabled the input may not be fully parsed. To detect that, compare stream.GetParsedLength() with the length of the original input.

Keywords

Any word that is not a custom token is stored as a single tokenizer.TokenKeyword. A keyword can contain unicode characters, and can be configured to contain additional symbols such as numbers and underscores (see AllowKeywordSymbols).

stream := parser.ParseString(`one 二 три`)
stream: [
    {Key: tokenizer.TokenKeyword, Value: "one"},
    {Key: tokenizer.TokenKeyword, Value: "二"},
    {Key: tokenizer.TokenKeyword, Value: "три"},
]

Keywords can be extended with parser.AllowKeywordSymbols(majorSymbols, minorSymbols):

  • Major symbols may appear anywhere in the keyword — at the beginning, in the middle and at the end.
  • Minor symbols may appear only in the middle and at the end (not at the beginning).
parser.AllowKeywordSymbols(tokenizer.Underscore, tokenizer.Numbers)
// allows: "_one23", "__one2__two3"

parser.AllowKeywordSymbols([]rune{'_', '@'}, tokenizer.Numbers)
// allows: "one@23", "@_one_two23", "_one23", "_one2_two3", "@@one___two@_9"
Integer number

Any integer is stored as one token with the key tokenizer.TokenInteger:

stream := parser.ParseString(`223 999`)
stream: [
    {Key: tokenizer.TokenInteger, Value: "223"},
    {Key: tokenizer.TokenInteger, Value: "999"},
]

Use token.ValueInt64() to get the value as int64:

stream := parser.ParseString("123")
fmt.Printf("Token is %d", stream.CurrentToken().ValueInt64()) // Token is 123

Underscores between digits (e.g. 1_000) can be allowed with parser.AllowNumberUnderscore().

Float number

Any float is stored as one token with the key tokenizer.TokenFloat. A float may

  • have a fractional point, e.g. 1.2
  • have an exponent, e.g. 1e6
  • use lower- or upper-case e/E in the exponent, e.g. 1E6, 1e6
  • have a sign in the exponent, e.g. 1e-6, 1e+6
stream := parser.ParseString(`1.3e-8`)
stream: [
    {Key: tokenizer.TokenFloat, Value: "1.3e-8"},
]

Use token.ValueFloat64() to get the value as float64:

stream := parser.ParseString("1.3e2")
fmt.Printf("Token is %g", stream.CurrentToken().ValueFloat64()) // Token is 130
Framed string

A string that is enclosed between two tokens is called a framed string. The most common example is a quoted string such as "one two", where the quotes are the frame (edge) tokens.

Define a framed string with parser.DefineStringToken(key, startToken, endToken). SetEscapeSymbol makes the escape character (usually a backslash) ignore the closing frame, and AddSpecialStrings lists the sequences that the escape character can unescape:

const TokenDoubleQuoted = 10
// ...
parser.DefineStringToken(TokenDoubleQuoted, `"`, `"`).
	SetEscapeSymbol(tokenizer.BackSlash).
	AddSpecialStrings([]string{`"`})

stream := parser.ParseString(`"two \"three"`)
stream: [
    {Key: tokenizer.TokenString, Value: `"two \"three"`},
]

The raw value (token.Value() / token.ValueString()) includes the frame tokens and escape symbols. Use token.ValueUnescapedString() (or token.ValueUnescaped() for []byte) to get the string without the frame tokens and with escape sequences resolved:

value := stream.CurrentToken().ValueUnescapedString() // two "three

token.StringKey() returns the key that was passed to DefineStringToken:

if stream.CurrentToken().StringKey() == TokenDoubleQuoted {
	// ...
}
Injections in a framed string

A framed string can contain embedded expressions (injections) that are parsed as regular tokens, for example "one {{ two }} three". The pieces of the string before, between and after the injections are emitted as tokenizer.TokenStringFragment tokens (they keep the frame quote and the surrounding whitespace); the injected part is parsed with the full set of tokens.

const (
	TokenOpenInjection  = 1
	TokenCloseInjection = 2
	TokenQuotedString   = 3
)

parser := tokenizer.New()
parser.DefineTokens(TokenOpenInjection, []string{"{{"})
parser.DefineTokens(TokenCloseInjection, []string{"}}"})
parser.DefineStringToken(TokenQuotedString, `"`, `"`).
	AddInjection(TokenOpenInjection, TokenCloseInjection)

stream := parser.ParseString(`"one {{ two }} three"`)
stream: [
    {Key: tokenizer.TokenStringFragment, Value: `"one `},
    {Key: TokenOpenInjection,            Value: "{{"},
    {Key: tokenizer.TokenKeyword,        Value: "two"},
    {Key: TokenCloseInjection,           Value: "}}"},
    {Key: tokenizer.TokenStringFragment, Value: ` three"`},
]

Use cases: parsing templates and placeholders.

User-defined tokens

Custom tokens (operators, punctuation, brackets, ...) are registered with parser.DefineTokens(key, tokens). The key must be a positive integer; a single key can map to multiple token strings. When several tokens can match at the same position, the longest one wins (e.g. >= is preferred over >).

const (
	TokenCurlyOpen TokenKey = iota + 1
	TokenCurlyClose
	TokenSquareOpen
	TokenSquareClose
	TokenColon
	TokenComma
	TokenDoubleQuoted
)

// a minimal JSON tokenizer
parser := tokenizer.New()
parser.
	DefineTokens(TokenCurlyOpen, []string{"{"}).
	DefineTokens(TokenCurlyClose, []string{"}"}).
	DefineTokens(TokenSquareOpen, []string{"["}).
	DefineTokens(TokenSquareClose, []string{"]"}).
	DefineTokens(TokenColon, []string{":"}).
	DefineTokens(TokenComma, []string{","}).
	DefineStringToken(TokenDoubleQuoted, `"`, `"`).
	SetEscapeSymbol(tokenizer.BackSlash).
	AddSpecialStrings(tokenizer.DefaultSpecialString)

stream := parser.ParseString(`{"key": [1]}`)

See example_test.go for a complete JSON parser built on top of this configuration.

Stream API

The *Stream is a bidirectional iterator over the parsed tokens. Common methods:

Method Description
IsValid() bool true while the pointer is on a real token.
GoNext() *Stream Move to the next token (loads the next chunk in stream mode).
GoPrev() *Stream Move to the previous token (bounded by SetHistorySize).
GoTo(id int) *Stream Move to a token by its id.
CurrentToken() *Token The current token (a TokenUndef token when out of range).
NextToken() / PrevToken() *Token Peek without moving the pointer.
GoNextIfNextIs(key, ...) bool Advance only if the next token matches.
IsNextSequence(keys...) bool Check that the following tokens match a sequence.
GetSnippet(before, after int) []Token Tokens around the current one.
GetParsedLength() int Number of bytes parsed so far.
Close() Release tokens back to the pool.

Token accessors:

Method Description
Key() TokenKey The token key.
Is(key, ...keys) bool Whether the token matches any of the keys.
Value() []byte / ValueString() string The raw value from the source.
ValueInt64() int64 / ValueFloat64() float64 The numeric value.
ValueUnescaped() []byte / ValueUnescapedString() string A framed string without frame tokens and escapes.
StringKey() TokenKey The key defined in DefineStringToken.
Line() int / Offset() int Position in the input (line starts at 1).
Indent() []byte Whitespace before the token.

Do not store a *Token returned by the stream — the underlying object may be reused as the pointer moves. Copy the value if you need to keep it.

Known issues

  • A zero byte (\x00) in the input stops parsing.

Benchmark

Parse a string / byte slice:

pkg: tokenizer
cpu: Intel(R) Core(TM) i7-7820HQ CPU @ 2.90GHz
BenchmarkParseBytes
    stream_test.go:251: Speed: 70 bytes string with 19.689µs: 3555284 byte/sec
    stream_test.go:251: Speed: 7000 bytes string with 848.163µs: 8253130 byte/sec
    stream_test.go:251: Speed: 700000 bytes string with 75.685945ms: 9248744 byte/sec
    stream_test.go:251: Speed: 11093670 bytes string with 1.16611538s: 9513355 byte/sec
BenchmarkParseBytes-8   	  158481	      7358 ns/op

Parse an infinite stream:

pkg: tokenizer
cpu: Intel(R) Core(TM) i7-7820HQ CPU @ 2.90GHz
BenchmarkParseInfStream
    stream_test.go:226: Speed: 70 bytes at 33.826µs: 2069414 byte/sec
    stream_test.go:226: Speed: 7000 bytes at 627.357µs: 11157921 byte/sec
    stream_test.go:226: Speed: 700000 bytes at 27.675799ms: 25292856 byte/sec
    stream_test.go:226: Speed: 30316440 bytes at 1.18061702s: 25678471 byte/sec
BenchmarkParseInfStream-8   	  433092	      2726 ns/op
PASS

Documentation

Overview

Package tokenizer provides a high performance generic tokenizer (lexer) that can parse any string, slice or infinite buffer to any tokens. It is highly customizable and can be used, for example, by higher level parsers for writing DSLs.

Index

Constants

View Source
const BackSlash = '\\'

BackSlash just backslash byte

View Source
const DefaultChunkSize = 4096

DefaultChunkSize default chunk size for reader.

Variables

View Source
var DefaultSpecialString = []string{
	"\\",
	"n",
	"r",
	"t",
}

DefaultSpecialString is default escaped symbols.

View Source
var DefaultStringEscapes = map[byte]byte{
	'n':  '\n',
	'r':  '\r',
	't':  '\t',
	'\\': '\\',
}

DefaultStringEscapes is default escaped symbols. Those symbols are often used everywhere.

Deprecated: use DefaultSpecialString and AddSpecialStrings

View Source
var DefaultWhiteSpaces = []byte{' ', '\t', '\n', '\r'}
View Source
var Numbers = []rune{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
View Source
var Underscore = []rune{'_'}

Functions

This section is empty.

Types

type QuoteInjectSettings

type QuoteInjectSettings struct {
	// Token type witch opens quoted string.
	StartKey TokenKey
	// Token type witch closes quoted string.
	EndKey TokenKey
}

QuoteInjectSettings describes open injection token and close injection token.

type Stream

type Stream struct {
	// contains filtered or unexported fields
}

Stream iterator via parsed tokens. If data reads from an infinite buffer, then the iterator will be read data from the reader chunk-by-chunk.

func NewInfStream

func NewInfStream(p *parsing) *Stream

NewInfStream creates new stream with active parser.

func NewStream

func NewStream(p *parsing) *Stream

NewStream creates a new parsed stream of tokens.

func (*Stream) Close

func (s *Stream) Close()

Close releases all token objects to pool

func (*Stream) CurrentToken

func (s *Stream) CurrentToken() *Token

CurrentToken always returns the token. If the pointer is not valid (see IsValid), CurrentToken will be return TokenUndef token. Do not save result (Token) into variables — current token may be changed at any time.

func (*Stream) GetParsedLength

func (s *Stream) GetParsedLength() int

GetParsedLength returns currently count parsed bytes.

func (*Stream) GetSnippet

func (s *Stream) GetSnippet(before, after int) []Token

GetSnippet returns slice of tokens. Slice generated from current token position and include tokens before and after current token.

func (*Stream) GetSnippetAsString

func (s *Stream) GetSnippetAsString(before, after, maxStringLength int) string

GetSnippetAsString returns tokens before and after current token as string. `maxStringLength` specifies max length of each token string. Zero — unlimited token string length. If string is greater than maxLength method removes some runes in the middle of the string.

func (*Stream) GoNext

func (s *Stream) GoNext() *Stream

GoNext moves the stream pointer to the next token. If there is no token, it initiates the parsing of the next chunk of data. If there is no data, the pointer will point to the TokenUndef token.

func (*Stream) GoNextIfNextIs

func (s *Stream) GoNextIfNextIs(key TokenKey, otherKeys ...TokenKey) bool

GoNextIfNextIs moves the stream pointer to the next token if the next token has specific token keys. If keys matched pointer will be updated and the method returned true. Otherwise, returned false.

func (*Stream) GoPrev

func (s *Stream) GoPrev() *Stream

GoPrev moves the pointer of stream to the next token. The number of possible calls is limited if you specified SetHistorySize. If the beginning of the stream or the end of the history is reached, the pointer will point to the TokenUndef token.

func (*Stream) GoTo

func (s *Stream) GoTo(id int) *Stream

GoTo moves the pointer of stream to specific token.

func (*Stream) HeadToken

func (s *Stream) HeadToken() *Token

HeadToken returns the pointer to head-token. Parser may change Head token if history size is enabled.

func (*Stream) IsAnyNextSequence added in v1.3.0

func (s *Stream) IsAnyNextSequence(keys ...[]TokenKey) bool

IsAnyNextSequence checks that at least one token from each group is contained in a sequence of tokens

func (*Stream) IsNextSequence added in v1.3.0

func (s *Stream) IsNextSequence(keys ...TokenKey) bool

IsNextSequence checks if these are next tokens in exactly the same sequence as specified.

func (*Stream) IsValid

func (s *Stream) IsValid() bool

IsValid checks if stream is valid. This means that the pointer has not reached the end of the stream.

func (*Stream) NextToken

func (s *Stream) NextToken() *Token

NextToken returns next token from the stream. If next token doesn't exist, the method returns TypeUndef token. Do not save a result (Token) into variables — the next token may be changed at any time.

func (*Stream) PrevToken

func (s *Stream) PrevToken() *Token

PrevToken returns previous token from the stream. If the previous token doesn't exist, the method returns TypeUndef token. Do not save a result (Token) into variables — the previous token may be changed at any time.

func (*Stream) SetHistorySize

func (s *Stream) SetHistorySize(size int) *Stream

SetHistorySize sets the number of tokens that should remain after the current token

func (*Stream) String

func (s *Stream) String() string

type StringSettings

type StringSettings struct {
	Key          TokenKey
	StartToken   []byte
	EndToken     []byte
	EscapeSymbol byte
	SpecSymbols  [][]byte
	Injects      []QuoteInjectSettings
}

StringSettings describes framed(quoted) string tokens like quoted strings.

func (*StringSettings) AddInjection

func (q *StringSettings) AddInjection(startTokenKey, endTokenKey TokenKey) *StringSettings

AddInjection configure injection in to string. Injection - parsable fragment of framed(quoted) string. Often used for parsing of placeholders or template expressions in the framed string.

func (*StringSettings) AddSpecialStrings added in v1.4.0

func (q *StringSettings) AddSpecialStrings(special []string) *StringSettings

AddSpecialStrings set mapping of all escapable strings for escape symbol, like \n, \t, \r.

func (*StringSettings) SetEscapeSymbol

func (q *StringSettings) SetEscapeSymbol(symbol byte) *StringSettings

SetEscapeSymbol set escape symbol for framed(quoted) string. Escape symbol allows ignoring close token of framed string. Also, escape symbol allows using special symbols in the frame strings, like \n, \t.

func (*StringSettings) SetSpecialSymbols deprecated

func (q *StringSettings) SetSpecialSymbols(special map[byte]byte) *StringSettings

SetSpecialSymbols set mapping of all escapable symbols for escape symbol, like \n, \t, \r.

Deprecated: use AddSpecialStrings

type Token

type Token struct {
	// contains filtered or unexported fields
}

Token struct describe one token.

func (*Token) ID

func (t *Token) ID() int

ID returns id of token. Id is the sequence number of tokens in the stream.

func (*Token) Indent

func (t *Token) Indent() []byte

Indent returns spaces before the token.

func (*Token) Is

func (t *Token) Is(key TokenKey, keys ...TokenKey) bool

Is checks if the token has any of these keys.

func (*Token) IsFloat

func (t *Token) IsFloat() bool

IsFloat checks if this token is float — the key is TokenFloat.

func (*Token) IsInteger

func (t *Token) IsInteger() bool

IsInteger checks if this token is integer — the key is TokenInteger.

func (*Token) IsKeyword

func (t *Token) IsKeyword() bool

IsKeyword checks if this is keyword — the key is TokenKeyword.

func (*Token) IsNumber

func (t *Token) IsNumber() bool

IsNumber checks if this token is integer or float — the key is TokenInteger or TokenFloat.

func (*Token) IsString

func (t *Token) IsString() bool

IsString checks if current token is a quoted string. Token key may be TokenString or TokenStringFragment.

func (*Token) IsValid

func (t *Token) IsValid() bool

IsValid checks if this token is valid — the key is not TokenUndef.

func (*Token) Key

func (t *Token) Key() TokenKey

Key returns the key of the token pointed to by the pointer. If pointer is not valid (see IsValid) TokenUndef will be returned.

func (*Token) Line

func (t *Token) Line() int

Line returns line number in input string. Line numbers starts from 1.

func (*Token) Offset

func (t *Token) Offset() int

Offset returns the byte position in input string (from start).

func (*Token) String

func (t *Token) String() string

String returns a multiline string with the token's information.

func (*Token) StringKey

func (t *Token) StringKey() TokenKey

StringKey returns key of string. If key not defined for string TokenString will be returned.

func (*Token) StringSettings

func (t *Token) StringSettings() *StringSettings

StringSettings returns StringSettings structure if token is framed string.

func (*Token) Value

func (t *Token) Value() []byte

Value returns value of current token as slice of bytes from source. If current token is invalid value returns nil.

Do not change bytes in the slice. Copy slice before change.

func (*Token) ValueFloat deprecated

func (t *Token) ValueFloat() float64

Deprecated: use ValueFloat64

func (*Token) ValueFloat64 added in v1.4.0

func (t *Token) ValueFloat64() float64

ValueFloat64 returns value as float64. If the token is not TokenInteger or TokenFloat then method returns zero. Method doesn't use cache — each call starts a number parser.

func (*Token) ValueInt deprecated

func (t *Token) ValueInt() int64

Deprecated: use ValueInt64

func (*Token) ValueInt64 added in v1.4.0

func (t *Token) ValueInt64() int64

ValueInt64 returns value as int64. If the token is float the result wild be round by math's rules. If the token is not TokenInteger or TokenFloat then method returns zero Method doesn't use cache — each call starts a number parser.

func (*Token) ValueString

func (t *Token) ValueString() string

ValueString returns value of the token as string. If the token is TokenUndef method returns empty string.

func (*Token) ValueUnescaped

func (t *Token) ValueUnescaped() []byte

ValueUnescaped returns clear (unquoted) string

  • without edge-tokens (quotes)
  • with character escaping handling

For example quoted string

"one \"two\"\t three"

transforms to

one "two"		three

Method doesn't use cache. Each call starts a string parser.

func (*Token) ValueUnescapedString

func (t *Token) ValueUnescapedString() string

ValueUnescapedString like as ValueUnescaped but returns string.

type TokenKey

type TokenKey int

TokenKey token type identifier

const (
	// TokenUnknown means that this token not embedded token and not user defined.
	TokenUnknown TokenKey = -6
	// TokenStringFragment means that this is only fragment of the quoted string with injections.
	// For example, "one {{ two }} three", where "one " and " three" — TokenStringFragment
	TokenStringFragment TokenKey = -5
	// TokenString means that this token is quoted string.
	// For example, "one two"
	TokenString TokenKey = -4
	// TokenFloat means that this token is a float number with point and/or exponent.
	// For example, 1.2, 1e6, 1E-6
	TokenFloat TokenKey = -3
	// TokenInteger means that this token is an integer number.
	// For example, 3, 49983
	TokenInteger TokenKey = -2
	// TokenKeyword means that this token is word.
	// For example, one, two, три
	TokenKeyword TokenKey = -1
	// TokenUndef means that token doesn't exist.
	// Then stream out of range of a token list any getter or checker will return TokenUndef token.
	TokenUndef TokenKey = 0
)

type Tokenizer

type Tokenizer struct {
	// contains filtered or unexported fields
}

Tokenizer stores all token configuration and behaviors.

func New

func New() *Tokenizer

New creates new tokenizer.

func (*Tokenizer) AllowKeywordSymbols added in v1.4.0

func (t *Tokenizer) AllowKeywordSymbols(majorSymbols []rune, minorSymbols []rune) *Tokenizer

AllowKeywordSymbols sets major and minor symbols for keywords. Major symbols (any quantity) might be in the beginning, at the middle and at the end of keyword. Minor symbols (any quantity) might be at the middle and at the end of the keyword.

parser.AllowKeywordSymbols(tokenizer.Underscore, tokenizer.Numbers)
// allows: "_one23", "__one2__two3"
parser.AllowKeywordSymbols([]rune{'_', '@'}, tokenizer.Numbers)
// allows: "one@23", "@_one_two23", "_one23", "_one2_two3", "@@one___two@_9"

Beware, the tokenizer does not control consecutive duplicates of these runes.

func (*Tokenizer) AllowKeywordUnderscore deprecated

func (t *Tokenizer) AllowKeywordUnderscore() *Tokenizer

AllowKeywordUnderscore allows underscore symbol in keywords, like `one_two` or `_three`

Deprecated: use AllowKeywordSymbols

func (*Tokenizer) AllowNumberUnderscore added in v1.4.0

func (t *Tokenizer) AllowNumberUnderscore() *Tokenizer

AllowNumberUnderscore allows underscore symbol in numbers, like `1_000`

func (*Tokenizer) AllowNumbersInKeyword deprecated

func (t *Tokenizer) AllowNumbersInKeyword() *Tokenizer

AllowNumbersInKeyword allows numbers in keywords, like `one1` or `r2d2` The method allows numbers in keywords, but the keyword itself must not start with a number. There should be no spaces between letters and numbers.

Deprecated: use AllowKeywordSymbols

func (*Tokenizer) DefineStringToken

func (t *Tokenizer) DefineStringToken(key TokenKey, startToken, endToken string) *StringSettings

DefineStringToken defines a token string. For example, a piece of data surrounded by quotes: "string in quotes" or 'string on single quotes'. Arguments startToken and endToken defines open and close "quotes".

  • `t.DefineStringToken(10, "`", "`")` - parse string "one `two three`" will be parsed as [{key: TokenKeyword, value: "one"}, {key: TokenString, value: "`two three`"}]

  • `t.DefineStringToken(11, "//", "\n")` - parse string "parse // like comment\n" will be parsed as [{key: TokenKeyword, value: "parse"}, {key: TokenString, value: "// like comment"}]

func (*Tokenizer) DefineTokens

func (t *Tokenizer) DefineTokens(key TokenKey, tokens []string) *Tokenizer

DefineTokens add custom token. The `key` is the identifier of `tokens`, `tokens` — slice of tokens as string. If a key already exists, tokens will be rewritten.

func (*Tokenizer) ParseBytes

func (t *Tokenizer) ParseBytes(str []byte) *Stream

ParseBytes parse and convert slice of bytes into stream of tokens.

func (*Tokenizer) ParseStream

func (t *Tokenizer) ParseStream(r io.Reader, bufferSize uint) *Stream

ParseStream parse and convert infinite stream of bytes into infinite stream of tokens.

func (*Tokenizer) ParseString

func (t *Tokenizer) ParseString(str string) *Stream

ParseString parse string into stream of tokens.

func (*Tokenizer) SetWhiteSpaces

func (t *Tokenizer) SetWhiteSpaces(ws []byte) *Tokenizer

SetWhiteSpaces sets custom whitespace symbols between tokens. By default: `{' ', '\t', '\n', '\r'}`

func (*Tokenizer) StopOnUndefinedToken

func (t *Tokenizer) StopOnUndefinedToken() *Tokenizer

StopOnUndefinedToken stops parsing if unknown token detected.

Jump to

Keyboard shortcuts

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