From a65a9325aaebd1499a8e523463cc023124f8536a Mon Sep 17 00:00:00 2001 From: Adam Scarr Date: Sun, 6 Aug 2017 17:02:39 +1000 Subject: Get the HTML parser working --- combinator.go | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) (limited to 'combinator.go') diff --git a/combinator.go b/combinator.go index 2b6b8a3..1f1317c 100644 --- a/combinator.go +++ b/combinator.go @@ -1,5 +1,10 @@ package parsec +import ( + "bytes" + "fmt" +) + func Nil(p Pointer) (Node, Pointer) { return nil, p } @@ -29,7 +34,7 @@ func And(parsers ...Parserish) Parser { } nodes = append(nodes, node) } - return NewSequence(p.pos, nodes...), newP + return nodes, newP } } @@ -109,6 +114,53 @@ func manyImpl(min int, op Parserish, until Parserish, sep ...Parserish) Parser { break } } - return NewSequence(p.pos, nodes...), newP + return nodes, newP + } +} + +func Maybe(parser Parserish) Parser { + realParser := Parsify(parser) + + return func(p Pointer) (Node, Pointer) { + node, newP := realParser(p) + if IsError(node) { + return nil, p + } + return node, newP + } +} + +func Map(parser Parserish, f func(n Node) Node) Parser { + p := Parsify(parser) + + return func(ptr Pointer) (Node, Pointer) { + node, newPtr := p(ptr) + if IsError(node) { + return node, ptr + } + + return f(node), newPtr + } +} + +func flatten(n Node) string { + if s, ok := n.(string); ok { + return s } + + if nodes, ok := n.([]Node); ok { + sbuf := &bytes.Buffer{} + for _, node := range nodes { + sbuf.WriteString(flatten(node)) + } + return sbuf.String() + } + + panic(fmt.Errorf("Dont know how to flatten %t", n)) +} + +func Merge(parser Parserish) Parser { + return Map(parser, func(n Node) Node { + return flatten(n) + }) } -- cgit v1.2.3