*Node -> Node
This commit is contained in:
parent
132876fce4
commit
88aaf567a5
@ -4,8 +4,8 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Nil = NewParser("Nil", func(ps *State) *Node {
|
var Nil = NewParser("Nil", func(ps *State) Node {
|
||||||
return nil
|
return Node{}
|
||||||
})
|
})
|
||||||
|
|
||||||
func And(parsers ...Parserish) Parser {
|
func And(parsers ...Parserish) Parser {
|
||||||
@ -15,26 +15,24 @@ func And(parsers ...Parserish) Parser {
|
|||||||
|
|
||||||
parserfied := ParsifyAll(parsers...)
|
parserfied := ParsifyAll(parsers...)
|
||||||
|
|
||||||
return NewParser("And()", func(ps *State) *Node {
|
return NewParser("And()", func(ps *State) Node {
|
||||||
var nodes = make([]*Node, 0, len(parserfied))
|
var nodes = make([]Node, 0, len(parserfied))
|
||||||
startpos := ps.Pos
|
startpos := ps.Pos
|
||||||
for _, parser := range parserfied {
|
for _, parser := range parserfied {
|
||||||
node := parser(ps)
|
node := parser(ps)
|
||||||
if ps.Errored() {
|
if ps.Errored() {
|
||||||
ps.Pos = startpos
|
ps.Pos = startpos
|
||||||
return nil
|
return Node{}
|
||||||
}
|
}
|
||||||
if node != nil {
|
|
||||||
nodes = append(nodes, node)
|
nodes = append(nodes, node)
|
||||||
}
|
}
|
||||||
}
|
return Node{Children: nodes}
|
||||||
return &Node{Children: nodes}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func NoAutoWS(parser Parserish) Parser {
|
func NoAutoWS(parser Parserish) Parser {
|
||||||
parserfied := Parsify(parser)
|
parserfied := Parsify(parser)
|
||||||
return func(ps *State) *Node {
|
return func(ps *State) Node {
|
||||||
ps.NoAutoWS = true
|
ps.NoAutoWS = true
|
||||||
|
|
||||||
ret := parserfied(ps)
|
ret := parserfied(ps)
|
||||||
@ -51,7 +49,7 @@ func Any(parsers ...Parserish) Parser {
|
|||||||
|
|
||||||
parserfied := ParsifyAll(parsers...)
|
parserfied := ParsifyAll(parsers...)
|
||||||
|
|
||||||
return NewParser("Any()", func(ps *State) *Node {
|
return NewParser("Any()", func(ps *State) Node {
|
||||||
longestError := Error{}
|
longestError := Error{}
|
||||||
startpos := ps.Pos
|
startpos := ps.Pos
|
||||||
for _, parser := range parserfied {
|
for _, parser := range parserfied {
|
||||||
@ -68,7 +66,7 @@ func Any(parsers ...Parserish) Parser {
|
|||||||
|
|
||||||
ps.Error = longestError
|
ps.Error = longestError
|
||||||
ps.Pos = startpos
|
ps.Pos = startpos
|
||||||
return nil
|
return Node{}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,9 +94,9 @@ func manyImpl(min int, op Parserish, until Parserish, sep ...Parserish) Parser {
|
|||||||
sepParser = Parsify(sep[0])
|
sepParser = Parsify(sep[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
return func(ps *State) *Node {
|
return func(ps *State) Node {
|
||||||
var node *Node
|
var node Node
|
||||||
nodes := make([]*Node, 0, 20)
|
nodes := make([]Node, 0, 20)
|
||||||
startpos := ps.Pos
|
startpos := ps.Pos
|
||||||
for {
|
for {
|
||||||
tempPos := ps.Pos
|
tempPos := ps.Pos
|
||||||
@ -109,7 +107,7 @@ func manyImpl(min int, op Parserish, until Parserish, sep ...Parserish) Parser {
|
|||||||
if len(nodes) < min {
|
if len(nodes) < min {
|
||||||
ps.Pos = startpos
|
ps.Pos = startpos
|
||||||
ps.ErrorHere("something else")
|
ps.ErrorHere("something else")
|
||||||
return nil
|
return Node{}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -120,7 +118,7 @@ func manyImpl(min int, op Parserish, until Parserish, sep ...Parserish) Parser {
|
|||||||
if ps.Errored() {
|
if ps.Errored() {
|
||||||
if len(nodes) < min {
|
if len(nodes) < min {
|
||||||
ps.Pos = startpos
|
ps.Pos = startpos
|
||||||
return nil
|
return Node{}
|
||||||
}
|
}
|
||||||
ps.ClearError()
|
ps.ClearError()
|
||||||
break
|
break
|
||||||
@ -134,37 +132,37 @@ func manyImpl(min int, op Parserish, until Parserish, sep ...Parserish) Parser {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &Node{Children: nodes}
|
return Node{Children: nodes}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Maybe(parser Parserish) Parser {
|
func Maybe(parser Parserish) Parser {
|
||||||
parserfied := Parsify(parser)
|
parserfied := Parsify(parser)
|
||||||
|
|
||||||
return NewParser("Maybe()", func(ps *State) *Node {
|
return NewParser("Maybe()", func(ps *State) Node {
|
||||||
node := parserfied(ps)
|
node := parserfied(ps)
|
||||||
if ps.Errored() {
|
if ps.Errored() {
|
||||||
ps.ClearError()
|
ps.ClearError()
|
||||||
return nil
|
return Node{}
|
||||||
}
|
}
|
||||||
|
|
||||||
return node
|
return node
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func Map(parser Parserish, f func(n *Node) *Node) Parser {
|
func Map(parser Parserish, f func(n Node) Node) Parser {
|
||||||
p := Parsify(parser)
|
p := Parsify(parser)
|
||||||
|
|
||||||
return NewParser("Map()", func(ps *State) *Node {
|
return NewParser("Map()", func(ps *State) Node {
|
||||||
node := p(ps)
|
node := p(ps)
|
||||||
if ps.Errored() {
|
if ps.Errored() {
|
||||||
return nil
|
return Node{}
|
||||||
}
|
}
|
||||||
return f(node)
|
return f(node)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func flatten(n *Node) string {
|
func flatten(n Node) string {
|
||||||
if n.Token != "" {
|
if n.Token != "" {
|
||||||
return n.Token
|
return n.Token
|
||||||
}
|
}
|
||||||
@ -181,7 +179,7 @@ func flatten(n *Node) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Merge(parser Parserish) Parser {
|
func Merge(parser Parserish) Parser {
|
||||||
return NewParser("Merge()", Map(parser, func(n *Node) *Node {
|
return NewParser("Merge()", Map(parser, func(n Node) Node {
|
||||||
return &Node{Token: flatten(n)}
|
return Node{Token: flatten(n)}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
func TestNil(t *testing.T) {
|
func TestNil(t *testing.T) {
|
||||||
node, p2 := runParser("hello world", Nil)
|
node, p2 := runParser("hello world", Nil)
|
||||||
|
|
||||||
require.Nil(t, node)
|
require.Equal(t, Node{}, node)
|
||||||
require.Equal(t, 0, p2.Pos)
|
require.Equal(t, 0, p2.Pos)
|
||||||
require.False(t, p2.Errored())
|
require.False(t, p2.Errored())
|
||||||
}
|
}
|
||||||
@ -44,7 +44,7 @@ func TestMaybe(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("returns no errors", func(t *testing.T) {
|
t.Run("returns no errors", func(t *testing.T) {
|
||||||
node, p3 := runParser("hello world", Maybe("world"))
|
node, p3 := runParser("hello world", Maybe("world"))
|
||||||
require.Nil(t, node)
|
require.Equal(t, Node{}, node)
|
||||||
require.False(t, p3.Errored())
|
require.False(t, p3.Errored())
|
||||||
require.Equal(t, 0, p3.Pos)
|
require.Equal(t, 0, p3.Pos)
|
||||||
})
|
})
|
||||||
@ -70,7 +70,7 @@ func TestAny(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("Accepts nil matches", func(t *testing.T) {
|
t.Run("Accepts nil matches", func(t *testing.T) {
|
||||||
node, p2 := runParser("hello world!", Any(Exact("ffffff")))
|
node, p2 := runParser("hello world!", Any(Exact("ffffff")))
|
||||||
require.Nil(t, node)
|
require.Equal(t, Node{}, node)
|
||||||
require.Equal(t, 0, p2.Pos)
|
require.Equal(t, 0, p2.Pos)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -168,8 +168,8 @@ type htmlTag struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMap(t *testing.T) {
|
func TestMap(t *testing.T) {
|
||||||
parser := Map(And("<", Chars("a-zA-Z0-9"), ">"), func(n *Node) *Node {
|
parser := Map(And("<", Chars("a-zA-Z0-9"), ">"), func(n Node) Node {
|
||||||
return &Node{Result: htmlTag{n.Children[1].Token}}
|
return Node{Result: htmlTag{n.Children[1].Token}}
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("sucess", func(t *testing.T) {
|
t.Run("sucess", func(t *testing.T) {
|
||||||
@ -203,11 +203,11 @@ func TestMerge(t *testing.T) {
|
|||||||
|
|
||||||
func assertNilParser(t *testing.T, parser Parser) {
|
func assertNilParser(t *testing.T, parser Parser) {
|
||||||
node, p2 := runParser("fff", parser)
|
node, p2 := runParser("fff", parser)
|
||||||
require.Nil(t, node)
|
require.Equal(t, Node{}, node)
|
||||||
require.Equal(t, 0, p2.Pos)
|
require.Equal(t, 0, p2.Pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
func assertSequence(t *testing.T, node *Node, expected ...string) {
|
func assertSequence(t *testing.T, node Node, expected ...string) {
|
||||||
require.NotNil(t, node)
|
require.NotNil(t, node)
|
||||||
actual := []string{}
|
actual := []string{}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ type DebugParser struct {
|
|||||||
Calls int
|
Calls int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dp *DebugParser) Parse(ps *State) *Node {
|
func (dp *DebugParser) Parse(ps *State) Node {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
ret := dp.Next(ps)
|
ret := dp.Next(ps)
|
||||||
|
16
html/html.go
16
html/html.go
@ -18,28 +18,28 @@ var (
|
|||||||
tag Parser
|
tag Parser
|
||||||
|
|
||||||
identifier = NoAutoWS(Merge(And(WS(), Chars("a-zA-Z", 1), Chars("a-zA-Z0-9", 0))))
|
identifier = NoAutoWS(Merge(And(WS(), Chars("a-zA-Z", 1), Chars("a-zA-Z0-9", 0))))
|
||||||
text = Map(NotChars("<>"), func(n *Node) *Node {
|
text = Map(NotChars("<>"), func(n Node) Node {
|
||||||
return &Node{Result: n.Token}
|
return Node{Result: n.Token}
|
||||||
})
|
})
|
||||||
|
|
||||||
element = Any(text, &tag)
|
element = Any(text, &tag)
|
||||||
elements = Map(Kleene(element), func(n *Node) *Node {
|
elements = Map(Kleene(element), func(n Node) Node {
|
||||||
ret := []interface{}{}
|
ret := []interface{}{}
|
||||||
for _, child := range n.Children {
|
for _, child := range n.Children {
|
||||||
ret = append(ret, child.Result)
|
ret = append(ret, child.Result)
|
||||||
}
|
}
|
||||||
return &Node{Result: ret}
|
return Node{Result: ret}
|
||||||
})
|
})
|
||||||
|
|
||||||
attr = And(identifier, "=", Any(String('"'), String('\'')))
|
attr = And(identifier, "=", Any(String('"'), String('\'')))
|
||||||
attrs = Map(Kleene(attr), func(node *Node) *Node {
|
attrs = Map(Kleene(attr), func(node Node) Node {
|
||||||
attr := map[string]string{}
|
attr := map[string]string{}
|
||||||
|
|
||||||
for _, attrNode := range node.Children {
|
for _, attrNode := range node.Children {
|
||||||
attr[attrNode.Children[0].Token] = attrNode.Children[2].Token
|
attr[attrNode.Children[0].Token] = attrNode.Children[2].Token
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Node{Result: attr}
|
return Node{Result: attr}
|
||||||
})
|
})
|
||||||
|
|
||||||
tstart = And("<", identifier, attrs, ">")
|
tstart = And("<", identifier, attrs, ">")
|
||||||
@ -47,9 +47,9 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
tag = Map(And(tstart, elements, tend), func(node *Node) *Node {
|
tag = Map(And(tstart, elements, tend), func(node Node) Node {
|
||||||
openTag := node.Children[0]
|
openTag := node.Children[0]
|
||||||
return &Node{Result: Tag{
|
return Node{Result: Tag{
|
||||||
Name: openTag.Children[1].Token,
|
Name: openTag.Children[1].Token,
|
||||||
Attributes: openTag.Children[2].Result.(map[string]string),
|
Attributes: openTag.Children[2].Result.(map[string]string),
|
||||||
Body: node.Children[1].Result.([]interface{}),
|
Body: node.Children[1].Result.([]interface{}),
|
||||||
|
28
json/json.go
28
json/json.go
@ -9,42 +9,42 @@ import (
|
|||||||
var (
|
var (
|
||||||
value Parser
|
value Parser
|
||||||
|
|
||||||
_array = Map(And("[", Kleene(&value, ","), "]"), func(n *Node) *Node {
|
_array = Map(And("[", Kleene(&value, ","), "]"), func(n Node) Node {
|
||||||
ret := []interface{}{}
|
ret := []interface{}{}
|
||||||
for _, child := range n.Children[1].Children {
|
for _, child := range n.Children[1].Children {
|
||||||
ret = append(ret, child.Result)
|
ret = append(ret, child.Result)
|
||||||
}
|
}
|
||||||
return &Node{Result: ret}
|
return Node{Result: ret}
|
||||||
})
|
})
|
||||||
properties = Kleene(And(String('"'), ":", &value), ",")
|
properties = Kleene(And(String('"'), ":", &value), ",")
|
||||||
_object = Map(And("{", properties, "}"), func(n *Node) *Node {
|
_object = Map(And("{", properties, "}"), func(n Node) Node {
|
||||||
ret := map[string]interface{}{}
|
ret := map[string]interface{}{}
|
||||||
|
|
||||||
for _, prop := range n.Children[1].Children {
|
for _, prop := range n.Children[1].Children {
|
||||||
ret[prop.Children[0].Token] = prop.Children[2].Result
|
ret[prop.Children[0].Token] = prop.Children[2].Result
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Node{Result: ret}
|
return Node{Result: ret}
|
||||||
})
|
})
|
||||||
|
|
||||||
_null = Map("null", func(n *Node) *Node {
|
_null = Map("null", func(n Node) Node {
|
||||||
return &Node{Result: nil}
|
return Node{Result: nil}
|
||||||
})
|
})
|
||||||
|
|
||||||
_true = Map("true", func(n *Node) *Node {
|
_true = Map("true", func(n Node) Node {
|
||||||
return &Node{Result: true}
|
return Node{Result: true}
|
||||||
})
|
})
|
||||||
|
|
||||||
_false = Map("false", func(n *Node) *Node {
|
_false = Map("false", func(n Node) Node {
|
||||||
return &Node{Result: false}
|
return Node{Result: false}
|
||||||
})
|
})
|
||||||
|
|
||||||
_string = Map(String('"'), func(n *Node) *Node {
|
_string = Map(String('"'), func(n Node) Node {
|
||||||
return &Node{Result: n.Token}
|
return Node{Result: n.Token}
|
||||||
})
|
})
|
||||||
|
|
||||||
Y = Map(&value, func(n *Node) *Node {
|
Y = Map(&value, func(n Node) Node {
|
||||||
return &Node{Result: n.Result}
|
return Node{Result: n.Result}
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
32
parser.go
32
parser.go
@ -9,11 +9,11 @@ import (
|
|||||||
|
|
||||||
type Node struct {
|
type Node struct {
|
||||||
Token string
|
Token string
|
||||||
Children []*Node
|
Children []Node
|
||||||
Result interface{}
|
Result interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Parser func(*State) *Node
|
type Parser func(*State) Node
|
||||||
|
|
||||||
// Parserish types are any type that can be turned into a Parser by Parsify
|
// Parserish types are any type that can be turned into a Parser by Parsify
|
||||||
// These currently include *Parser and string literals.
|
// These currently include *Parser and string literals.
|
||||||
@ -35,13 +35,13 @@ func Parsify(p Parserish) Parser {
|
|||||||
switch p := p.(type) {
|
switch p := p.(type) {
|
||||||
case nil:
|
case nil:
|
||||||
return nil
|
return nil
|
||||||
case func(*State) *Node:
|
case func(*State) Node:
|
||||||
return NewParser("anonymous func", p)
|
return NewParser("anonymous func", p)
|
||||||
case Parser:
|
case Parser:
|
||||||
return p
|
return p
|
||||||
case *Parser:
|
case *Parser:
|
||||||
// Todo: Maybe capture this stack and on nil show it? Is there a good error library to do this?
|
// Todo: Maybe capture this stack and on nil show it? Is there a good error library to do this?
|
||||||
return func(ptr *State) *Node {
|
return func(ptr *State) Node {
|
||||||
return (*p)(ptr)
|
return (*p)(ptr)
|
||||||
}
|
}
|
||||||
case string:
|
case string:
|
||||||
@ -60,9 +60,9 @@ func ParsifyAll(parsers ...Parserish) []Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func WS() Parser {
|
func WS() Parser {
|
||||||
return NewParser("AutoWS", func(ps *State) *Node {
|
return NewParser("AutoWS", func(ps *State) Node {
|
||||||
ps.WS()
|
ps.WS()
|
||||||
return nil
|
return Node{}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,16 +81,16 @@ func ParseString(parser Parserish, input string) (result interface{}, remaining
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Exact(match string) Parser {
|
func Exact(match string) Parser {
|
||||||
return NewParser(match, func(ps *State) *Node {
|
return NewParser(match, func(ps *State) Node {
|
||||||
ps.AutoWS()
|
ps.AutoWS()
|
||||||
if !strings.HasPrefix(ps.Get(), match) {
|
if !strings.HasPrefix(ps.Get(), match) {
|
||||||
ps.ErrorHere(match)
|
ps.ErrorHere(match)
|
||||||
return nil
|
return Node{}
|
||||||
}
|
}
|
||||||
|
|
||||||
ps.Advance(len(match))
|
ps.Advance(len(match))
|
||||||
|
|
||||||
return &Node{Token: match}
|
return Node{Token: match}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ func charsImpl(matcher string, stopOn bool, repetition ...int) Parser {
|
|||||||
min, max := parseRepetition(1, -1, repetition...)
|
min, max := parseRepetition(1, -1, repetition...)
|
||||||
matches, ranges := parseMatcher(matcher)
|
matches, ranges := parseMatcher(matcher)
|
||||||
|
|
||||||
return func(ps *State) *Node {
|
return func(ps *State) Node {
|
||||||
ps.AutoWS()
|
ps.AutoWS()
|
||||||
matched := 0
|
matched := 0
|
||||||
for ps.Pos+matched < len(ps.Input) {
|
for ps.Pos+matched < len(ps.Input) {
|
||||||
@ -177,17 +177,17 @@ func charsImpl(matcher string, stopOn bool, repetition ...int) Parser {
|
|||||||
|
|
||||||
if matched < min {
|
if matched < min {
|
||||||
ps.ErrorHere(matcher)
|
ps.ErrorHere(matcher)
|
||||||
return nil
|
return Node{}
|
||||||
}
|
}
|
||||||
|
|
||||||
result := ps.Input[ps.Pos : ps.Pos+matched]
|
result := ps.Input[ps.Pos : ps.Pos+matched]
|
||||||
ps.Advance(matched)
|
ps.Advance(matched)
|
||||||
return &Node{Token: result}
|
return Node{Token: result}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func String(quote rune) Parser {
|
func String(quote rune) Parser {
|
||||||
return NewParser("string", func(ps *State) *Node {
|
return NewParser("string", func(ps *State) Node {
|
||||||
ps.AutoWS()
|
ps.AutoWS()
|
||||||
var r rune
|
var r rune
|
||||||
var w int
|
var w int
|
||||||
@ -195,7 +195,7 @@ func String(quote rune) Parser {
|
|||||||
r, matched = utf8.DecodeRuneInString(ps.Input[ps.Pos:])
|
r, matched = utf8.DecodeRuneInString(ps.Input[ps.Pos:])
|
||||||
if r != quote {
|
if r != quote {
|
||||||
ps.ErrorHere("\"")
|
ps.ErrorHere("\"")
|
||||||
return nil
|
return Node{}
|
||||||
}
|
}
|
||||||
|
|
||||||
result := &bytes.Buffer{}
|
result := &bytes.Buffer{}
|
||||||
@ -213,12 +213,12 @@ func String(quote rune) Parser {
|
|||||||
|
|
||||||
if r == quote {
|
if r == quote {
|
||||||
ps.Advance(matched)
|
ps.Advance(matched)
|
||||||
return &Node{Token: result.String()}
|
return Node{Token: result.String()}
|
||||||
}
|
}
|
||||||
result.WriteRune(r)
|
result.WriteRune(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
ps.ErrorHere("\"")
|
ps.ErrorHere("\"")
|
||||||
return nil
|
return Node{}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,8 @@ func TestParsify(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("parser funcs", func(t *testing.T) {
|
t.Run("parser funcs", func(t *testing.T) {
|
||||||
node := Parsify(func(p *State) *Node {
|
node := Parsify(func(p *State) Node {
|
||||||
return &Node{Token: "hello"}
|
return Node{Token: "hello"}
|
||||||
})(InputString("ffooo"))
|
})(InputString("ffooo"))
|
||||||
|
|
||||||
require.Equal(t, "hello", node.Token)
|
require.Equal(t, "hello", node.Token)
|
||||||
@ -45,7 +45,7 @@ func TestParsifyAll(t *testing.T) {
|
|||||||
require.Equal(t, "ff", result.Token)
|
require.Equal(t, "ff", result.Token)
|
||||||
|
|
||||||
result = parsers[1](InputString("ffooo"))
|
result = parsers[1](InputString("ffooo"))
|
||||||
require.Nil(t, result)
|
require.Equal(t, "", result.Token)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExact(t *testing.T) {
|
func TestExact(t *testing.T) {
|
||||||
@ -116,7 +116,7 @@ func TestChars(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestParseString(t *testing.T) {
|
func TestParseString(t *testing.T) {
|
||||||
Y := Map("hello", func(n *Node) *Node { return &Node{Result: n.Token} })
|
Y := Map("hello", func(n Node) Node { return Node{Result: n.Token} })
|
||||||
t.Run("partial match", func(t *testing.T) {
|
t.Run("partial match", func(t *testing.T) {
|
||||||
result, remaining, err := ParseString(Y, "hello world")
|
result, remaining, err := ParseString(Y, "hello world")
|
||||||
require.Equal(t, "hello", result)
|
require.Equal(t, "hello", result)
|
||||||
@ -159,7 +159,7 @@ func TestString(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func runParser(input string, parser Parser) (*Node, *State) {
|
func runParser(input string, parser Parser) (Node, *State) {
|
||||||
ps := InputString(input)
|
ps := InputString(input)
|
||||||
result := parser(ps)
|
result := parser(ps)
|
||||||
return result, ps
|
return result, ps
|
||||||
|
Loading…
Reference in New Issue
Block a user