63 lines
1.8 KiB
Go
63 lines
1.8 KiB
Go
package parser
|
|
|
|
import (
|
|
"bytes"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// stringBuffer is a string buffer implementation, which is used by the parser
|
|
// to efficiently accumulate runes from the input and eventually turn these
|
|
// into a string, either literal or interpreted.
|
|
type stringBuffer struct {
|
|
buffer bytes.Buffer
|
|
}
|
|
|
|
// reset resets the string buffer, in order to build a new string.
|
|
func (b *stringBuffer) reset() *stringBuffer {
|
|
b.buffer.Reset()
|
|
return b
|
|
}
|
|
|
|
// writeString adds the runes of the input string to the string buffer.
|
|
func (b *stringBuffer) writeString(s string) *stringBuffer {
|
|
for _, r := range s {
|
|
b.writeRune(r)
|
|
}
|
|
return b
|
|
}
|
|
|
|
// writeRune adds a single rune to the string buffer.
|
|
func (b *stringBuffer) writeRune(r rune) *stringBuffer {
|
|
b.buffer.WriteRune(r)
|
|
return b
|
|
}
|
|
|
|
// asLiteralString returns the string buffer as a literal string.
|
|
// Literal means that no escape sequences are processed.
|
|
func (b *stringBuffer) asLiteralString() string {
|
|
return b.buffer.String()
|
|
}
|
|
|
|
// asInterpretedString returns the string in its interpreted form.
|
|
// Interpreted means that escape sequences are handled in the way that Go would
|
|
// have, had it been inside double quotes. It translates for example escape
|
|
// sequences like "\n", "\t", \uXXXX" and "\UXXXXXXXX" into their string
|
|
// representations.
|
|
// Since the input might contain invalid escape sequences, this method
|
|
// also returns an error. When an error is returned, the returned string will
|
|
// contain the string as far as it could be interpreted.
|
|
func (b *stringBuffer) asInterpretedString() (string, error) {
|
|
var sb strings.Builder
|
|
tail := b.buffer.String()
|
|
for len(tail) > 0 {
|
|
r, _, newtail, err := strconv.UnquoteChar(tail, '"')
|
|
if err != nil {
|
|
return sb.String(), err
|
|
}
|
|
tail = newtail
|
|
sb.WriteRune(r)
|
|
}
|
|
return sb.String(), nil
|
|
}
|