2019-10-16 18:19:48 +09:00
|
|
|
package scanner
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
"github.com/goccy/go-yaml/token"
|
|
|
|
|
)
|
|
|
|
|
|
2019-10-21 12:53:30 +09:00
|
|
|
// Context context at scanning
|
2019-10-16 18:19:48 +09:00
|
|
|
type Context struct {
|
2019-12-04 23:58:06 +09:00
|
|
|
idx int
|
|
|
|
|
size int
|
|
|
|
|
src []rune
|
|
|
|
|
buf []rune
|
|
|
|
|
obuf []rune
|
|
|
|
|
tokens token.Tokens
|
|
|
|
|
isRawFolded bool
|
|
|
|
|
isLiteral bool
|
|
|
|
|
isFolded bool
|
|
|
|
|
isSingleLine bool
|
|
|
|
|
literalOpt string
|
2019-10-16 18:19:48 +09:00
|
|
|
}
|
|
|
|
|
|
2019-11-07 18:01:45 +09:00
|
|
|
func newContext(src []rune) *Context {
|
2019-10-16 18:19:48 +09:00
|
|
|
return &Context{
|
2019-12-04 23:58:06 +09:00
|
|
|
idx: 0,
|
|
|
|
|
size: len(src),
|
|
|
|
|
src: src,
|
|
|
|
|
tokens: token.Tokens{},
|
|
|
|
|
buf: make([]rune, 0, len(src)),
|
|
|
|
|
obuf: make([]rune, 0, len(src)),
|
|
|
|
|
isSingleLine: true,
|
2019-10-16 18:19:48 +09:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Context) resetBuffer() {
|
|
|
|
|
c.buf = c.buf[:0]
|
|
|
|
|
c.obuf = c.obuf[:0]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Context) isSaveIndentMode() bool {
|
|
|
|
|
return c.isLiteral || c.isFolded || c.isRawFolded
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Context) breakLiteral() {
|
|
|
|
|
c.isLiteral = false
|
|
|
|
|
c.isRawFolded = false
|
|
|
|
|
c.isFolded = false
|
|
|
|
|
c.literalOpt = ""
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Context) addToken(tk *token.Token) {
|
|
|
|
|
if tk == nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
c.tokens = append(c.tokens, tk)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Context) addBuf(r rune) {
|
|
|
|
|
c.buf = append(c.buf, r)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Context) addOriginBuf(r rune) {
|
|
|
|
|
c.obuf = append(c.obuf, r)
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-07 23:45:39 +09:00
|
|
|
func (c *Context) isDocument() bool {
|
|
|
|
|
return c.isLiteral || c.isFolded || c.isRawFolded
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-16 18:19:48 +09:00
|
|
|
func (c *Context) isEOS() bool {
|
|
|
|
|
return len(c.src)-1 <= c.idx
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-30 16:57:59 +09:00
|
|
|
func (c *Context) isNextEOS() bool {
|
|
|
|
|
return len(c.src)-1 <= c.idx+1
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-16 18:19:48 +09:00
|
|
|
func (c *Context) next() bool {
|
|
|
|
|
return c.idx < c.size
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Context) source(s, e int) string {
|
2019-11-07 17:18:17 +09:00
|
|
|
return string(c.src[s:e])
|
2019-10-16 18:19:48 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Context) previousChar() rune {
|
|
|
|
|
if c.idx > 0 {
|
2019-11-07 17:18:17 +09:00
|
|
|
return c.src[c.idx-1]
|
2019-10-16 18:19:48 +09:00
|
|
|
}
|
|
|
|
|
return rune(0)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Context) currentChar() rune {
|
2019-11-07 17:18:17 +09:00
|
|
|
return c.src[c.idx]
|
2019-10-16 18:19:48 +09:00
|
|
|
}
|
|
|
|
|
|
2019-10-21 12:53:30 +09:00
|
|
|
func (c *Context) nextChar() rune {
|
|
|
|
|
if c.size > c.idx+1 {
|
2019-11-07 17:18:17 +09:00
|
|
|
return c.src[c.idx+1]
|
2019-10-16 18:19:48 +09:00
|
|
|
}
|
|
|
|
|
return rune(0)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Context) repeatNum(r rune) int {
|
|
|
|
|
cnt := 0
|
|
|
|
|
for i := c.idx; i < c.size; i++ {
|
2019-11-07 17:18:17 +09:00
|
|
|
if c.src[i] == r {
|
2019-10-16 18:19:48 +09:00
|
|
|
cnt++
|
|
|
|
|
} else {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return cnt
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Context) progress(num int) {
|
|
|
|
|
c.idx += num
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Context) nextPos() int {
|
|
|
|
|
return c.idx + 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Context) bufferedSrc() string {
|
|
|
|
|
src := strings.TrimLeft(string(c.buf), " ")
|
|
|
|
|
src = strings.TrimRight(src, " ")
|
2019-11-08 16:48:54 +09:00
|
|
|
if len(src) > 0 && src[len(src)-1] == '\n' && c.isDocument() && c.literalOpt == "-" {
|
|
|
|
|
// remove end '\n' character
|
|
|
|
|
src = src[:len(src)-1]
|
|
|
|
|
}
|
2019-10-16 18:19:48 +09:00
|
|
|
return src
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Context) bufferedToken(pos *token.Position) *token.Token {
|
|
|
|
|
if c.idx == 0 {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
source := c.bufferedSrc()
|
|
|
|
|
if len(source) == 0 {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
tk := token.New(source, string(c.obuf), pos)
|
|
|
|
|
c.buf = c.buf[:0]
|
|
|
|
|
c.obuf = c.obuf[:0]
|
|
|
|
|
return tk
|
|
|
|
|
}
|