Documentation ¶
Overview ¶
Package stateful defines a nested stateful lexer.
This lexer is based heavily on the approach used by Chroma (and Pygments).
The lexer is a state machine defined by a map of rules keyed by state. Each rule is a named regex and optional operation to apply when the rule matches.
As a convenience, any Rule starting with a lowercase letter will be elided from output.
Lexing starts in the "Root" group. Each rule is matched in order, with the first successful match producing a lexeme. If the matching rule has an associated Action it will be executed. The name of each non-root rule is prefixed with the name of its group to yield the token identifier used during matching.
A state change can be introduced with the Action `Push(state)`. `Pop()` will return to the previous state.
To reuse rules from another state, use `Include(state)`.
As a special case, regexes containing backrefs in the form \N (where N is a digit) will match the corresponding capture group from the immediate parent group. This can be used to parse, among other things, heredocs.
See the example and tests in this package for details.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Action ¶ added in v0.7.0
type Action interface {
// contains filtered or unexported methods
}
A Action is applied when a rule matches.
type ActionFunc ¶ added in v0.7.0
ActionFunc is a function that is also a Action.
type Definition ¶
type Definition struct {
// contains filtered or unexported fields
}
Definition is the lexer.Definition.
func New ¶
func New(rules Rules) (*Definition, error)
New constructs a new stateful lexer from rules.
Example ¶
An example of parsing nested expressions within strings.
type Terminal struct { String *String ` @@` Ident string `| @Ident` } type Expr struct { Left *Terminal `@@` Op string `( @Oper` Right *Terminal ` @@)?` } type Fragment struct { Escaped string `( @Escaped` Expr *Expr ` | "${" @@ "}"` Text string ` | @Char)` } type String struct { Fragments []*Fragment `"\"" @@* "\""` } def, err := New(interpolatedRules) if err != nil { log.Fatal(err) } parser, err := participle.Build(&String{}, participle.Lexer(def)) if err != nil { log.Fatal(err) } actual := &String{} err = parser.ParseString(`"hello ${user + "??"}"`, actual) if err != nil { log.Fatal(err) } repr.Println(actual)
Output:
func NewSimple ¶ added in v0.7.0
func NewSimple(rules []Rule) (*Definition, error)
NewSimple creates a new stateful lexer with a single "Root" state.
func (*Definition) Symbols ¶
func (d *Definition) Symbols() map[string]rune
type RulesAction ¶ added in v0.7.0
type RulesAction interface {
// contains filtered or unexported methods
}
RulesAction is an optional interface that Actions can implement.
It is applied during rule construction to mutate the rule map.