summaryrefslogtreecommitdiff
path: root/parser.go
diff options
context:
space:
mode:
authorAdam Scarr <adam@vektah.net>2017-08-06 17:28:34 +1000
committerAdam Scarr <adam@vektah.net>2017-08-06 17:28:34 +1000
commit2c0c5b628fd0b8e7499574d379b4138630f886d7 (patch)
tree20be82a411649f8f80281c6f73977e0d797858eb /parser.go
parenta65a9325aaebd1499a8e523463cc023124f8536a (diff)
Add String parser
Diffstat (limited to 'parser.go')
-rw-r--r--parser.go34
1 files changed, 34 insertions, 0 deletions
diff --git a/parser.go b/parser.go
index 3c5d752..7599bf1 100644
--- a/parser.go
+++ b/parser.go
@@ -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
+ }
+}