Documentation
¶
Index ¶
- func ConvertAliases(i interface{}) interface{}
- type Capture
- type Node
- func (n *Node) Adopt(other *Node)
- func (n *Node) Children() []*Node
- func (n *Node) IsParent() bool
- func (n *Node) Remove() *Node
- func (n *Node) SetFirst(child *Node)
- func (n *Node) SetLast(child *Node)
- func (n *Node) SetNext(sibling *Node)
- func (n *Node) SetPrevious(sibling *Node)
- func (n *Node) String() string
- type ParseNode
- type Parser
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ConvertAliases ¶
func ConvertAliases(i interface{}) interface{}
ConvertAliases converts various default primitive types to aliases for type matching.
Types ¶
type Capture ¶
type Capture struct {
// Type of the node.
Type int
// Value is the expression to capture the value of the node.
Value interface{}
// Convert is an optional functions to change the type of the parsed value.
// e.g. convert "1" to an integer instead of the string itself.
Convert func(i string) interface{}
}
Capture is a structure to indicate that the value should be converted to a node. If one of the children returns a node, then that node gets returned
type Node ¶
type Node struct {
// Type of the node.
Type int
// Value of the node. Only possible if it has no children.
Value interface{}
// Parent is the parent node.
Parent *Node
// PreviousSibling is the previous sibling of the node.
PreviousSibling *Node
// NextSibling is the next sibling of the node.
NextSibling *Node
// FirstChild is the first child of the node.
FirstChild *Node
// LastChild is the last child of the node.
LastChild *Node
}
Node is a simple node in a tree with double linked lists instead of slices to keep track of its siblings and children. A node is either a value or a parent node.
func (*Node) IsParent ¶
IsParent returns whether the node has children and thus is not a value node.
func (*Node) SetPrevious ¶
SetPrevious inserts the given node as the previous sibling.
type Parser ¶
type Parser struct {
// contains filtered or unexported fields
}
Parser represents a general purpose AST parser.
func (*Parser) Expect ¶
Expect checks whether the buffer contains the given value.
Example (And) ¶
package main
import (
"fmt"
"github.com/di-wu/parser"
"github.com/di-wu/parser/ast"
"github.com/di-wu/parser/op"
)
func main() {
p, _ := ast.New([]byte("1 <= 2"))
digit := ast.Capture{
Type: 1,
Value: parser.CheckRuneFunc(func(r rune) bool {
return '0' <= r && r <= '9'
}),
}
fmt.Println(p.Expect(op.And{
digit, parser.CheckString(" <= "), digit,
}))
}
Output: [-01] [[001] 1, [001] 2] <nil>
Example (Capture) ¶
package main
import (
"fmt"
"github.com/di-wu/parser"
"github.com/di-wu/parser/ast"
"strconv"
)
func main() {
p, _ := ast.New([]byte("1 <= 2"))
digit := ast.Capture{
Value: parser.CheckRuneFunc(func(r rune) bool {
return '0' <= r && r <= '9'
}),
Convert: func(i string) interface{} {
v, _ := strconv.Atoi(i)
return v
},
}
lt := parser.CheckString(" <= ")
fmt.Println(p.Expect(digit))
fmt.Println(p.Expect(lt))
fmt.Println(p.Expect(digit))
}
Output: [000] 1 <nil> <nil> <nil> [000] 2 <nil>
Example (Class) ¶
package main
import (
"fmt"
"github.com/di-wu/parser"
"github.com/di-wu/parser/ast"
)
func main() {
p, _ := ast.New([]byte("1 <= 2"))
digit := func(p *parser.Parser) (*parser.Cursor, bool) {
r := p.Current()
return p.Mark(), '0' <= r && r <= '9'
}
lt := func(p *parser.Parser) (*parser.Cursor, bool) {
var last *parser.Cursor
for _, r := range []rune("<=") {
if p.Current() != r {
return nil, false
}
last = p.Mark()
p.Next()
}
return last, true
}
fmt.Println(p.Expect(digit))
_, _ = p.Expect(' ') // Skip space.
fmt.Println(p.Expect(lt))
_, _ = p.Expect(' ') // Skip space.
fmt.Println(p.Expect(digit))
}
Output: <nil> <nil> <nil> <nil> <nil> <nil>
Example (Not) ¶
package main
import (
"fmt"
"github.com/di-wu/parser/ast"
"github.com/di-wu/parser/op"
)
func main() {
p, _ := ast.New([]byte("bar"))
_, err := p.Expect(op.Not{Value: "bar"})
fmt.Println(err)
_, err = p.Expect(op.Not{Value: ast.Capture{
Value: "baz",
}})
fmt.Println(err)
}
Output: parse: expected op.Not {bar} but got "bar" <nil>
Example (Or) ¶
package main
import (
"fmt"
"github.com/di-wu/parser/ast"
"github.com/di-wu/parser/op"
)
func main() {
p, _ := ast.New([]byte("data"))
var (
d = ast.Capture{Value: 'd'}
da = ast.Capture{Value: "da"}
data = ast.Capture{Value: "data"}
a = ast.Capture{Value: 'a'}
at = ast.Capture{Value: "at"}
ata = ast.Capture{Value: "ata"}
t = ast.Capture{Value: 't'}
)
fmt.Println(p.Expect(op.Or{d, da, data}))
fmt.Println(p.Expect(op.Or{at, a, ata}))
fmt.Println(p.Expect(op.Or{d, t, op.Not{a}}))
}
Output: [000] d <nil> [000] at <nil> <nil> parse: expected op.Or [{0 100 <nil>} {0 116 <nil>} {{0 97 <nil>}}] but got "a"
Example (Parse_node) ¶
package main
import (
"fmt"
"github.com/di-wu/parser"
"github.com/di-wu/parser/ast"
"github.com/di-wu/parser/op"
"strconv"
)
func main() {
p, _ := ast.New([]byte("1 <= 2"))
fmt.Println(p.Expect(func(p *ast.Parser) (*ast.Node, error) {
digit := ast.Capture{
Value: parser.CheckRuneFunc(func(r rune) bool {
return '0' <= r && r <= '9'
}),
Convert: func(i string) interface{} {
v, _ := strconv.Atoi(i)
return v
},
}
return p.Expect(op.And{digit, parser.CheckString(" <= "), digit})
}))
}
Output: [-01] [[000] 1, [000] 2] <nil>
Example (Range) ¶
package main
import (
"fmt"
"github.com/di-wu/parser/ast"
"github.com/di-wu/parser/op"
)
func main() {
p, _ := ast.New([]byte("aaa"))
fmt.Println(p.Expect(ast.Capture{
Value: op.Min(3, 'a'),
})) // 3 * 'a'
p, _ = ast.New([]byte("aaa"))
fmt.Println(p.Expect(op.Min(4, 'a'))) // err
}
Output: [000] aaa <nil> <nil> parse: expected op.Range {4 -1 97} but got "aaa"
Example (Rune) ¶
package main
import (
"fmt"
"github.com/di-wu/parser/ast"
)
func main() {
p, _ := ast.New([]byte("data"))
fmt.Println(p.Expect('d'))
fmt.Println(p.Expect('d')) // Invalid.
fmt.Println(p.Expect('a'))
fmt.Println(p.Expect('t'))
fmt.Println(p.Expect('a'))
}
Output: <nil> <nil> <nil> parse: expected int32 100 but got "a" <nil> <nil> <nil> <nil> <nil> <nil>
Example (String) ¶
package main
import (
"fmt"
"github.com/di-wu/parser/ast"
)
func main() {
p, _ := ast.New([]byte("some data"))
fmt.Println(p.Expect("some"))
fmt.Println(p.Expect('_'))
_, _ = p.Expect(' ') // Skip space.
fmt.Println(p.Expect("data"))
}
Output: <nil> <nil> <nil> parse: expected int32 95 but got " " <nil> <nil>
Example (Xor) ¶
package main
import (
"fmt"
"github.com/di-wu/parser/ast"
"github.com/di-wu/parser/op"
)
func main() {
p, _ := ast.New([]byte("data"))
var (
d = ast.Capture{Value: 'd'}
da = ast.Capture{Value: "da"}
data = ast.Capture{Value: "data"}
a = ast.Capture{Value: 'a'}
t = ast.Capture{Value: 't'}
)
fmt.Println(p.Expect(op.XOr{d, da, data}))
fmt.Println(p.Expect(op.XOr{a, t}))
}
Output: <nil> parse: expected op.XOr [{0 100 <nil>} {0 da <nil>} {0 data <nil>}] but got "da" <nil> parse: expected op.XOr [{0 97 <nil>} {0 116 <nil>}] but got "d"
Click to show internal directories.
Click to hide internal directories.