diff options
author | Adam Scarr <adam@vektah.net> | 2017-08-06 17:02:39 +1000 |
---|---|---|
committer | Adam Scarr <adam@vektah.net> | 2017-08-06 17:02:39 +1000 |
commit | a65a9325aaebd1499a8e523463cc023124f8536a (patch) | |
tree | 2fb31800b67a3914a7204a28319a7aeb0ac649c7 /combinator.go | |
parent | 8b343d6360d0edc065b9b62ab5e708e907b45a92 (diff) |
Get the HTML parser working
Diffstat (limited to 'combinator.go')
-rw-r--r-- | combinator.go | 56 |
1 files changed, 54 insertions, 2 deletions
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) + }) } |