diff options
author | Adam Scarr <adam@vektah.net> | 2017-08-06 17:28:34 +1000 |
---|---|---|
committer | Adam Scarr <adam@vektah.net> | 2017-08-06 17:28:34 +1000 |
commit | 2c0c5b628fd0b8e7499574d379b4138630f886d7 (patch) | |
tree | 20be82a411649f8f80281c6f73977e0d797858eb /parser.go | |
parent | a65a9325aaebd1499a8e523463cc023124f8536a (diff) |
Add String parser
Diffstat (limited to 'parser.go')
-rw-r--r-- | parser.go | 34 |
1 files changed, 34 insertions, 0 deletions
@@ -1,6 +1,7 @@ package parsec import ( + "bytes" "fmt" "strings" "unicode/utf8" @@ -185,3 +186,36 @@ func WS(p Pointer) (Node, Pointer) { _, p2 := CharRun("\t\n\v\f\r \x85\xA0")(p) return nil, p2 } + +func String(quote rune) Parser { + return func(p Pointer) (Node, Pointer) { + var r rune + var w int + r, w = utf8.DecodeRuneInString(p.input[p.pos:]) + if r != quote { + return NewError(p.pos, `Expected "`), p + } + + matched := w + result := &bytes.Buffer{} + + for p.pos+matched < len(p.input) { + r, w = utf8.DecodeRuneInString(p.input[p.pos+matched:]) + matched += w + + if r == '\\' { + r, w = utf8.DecodeRuneInString(p.input[p.pos+matched:]) + result.WriteRune(r) + matched += w + continue + } + + if r == quote { + return result.String(), p.Advance(matched) + } + result.WriteRune(r) + } + + return NewError(p.pos, "Unterminated string"), p + } +} |