func isTemplateTextChar(c byte) bool {
	return !IsEndChar(c) && c != '$'
}
IsTemplateTextChar returns true for all not END chars and not $
package ogdl
import (
	"bytes"
	"errors"
	"io"
	"strconv"
	"unicode"
	"unicode/utf8"
)
const (
	bufSize  = 4096
	halfSize = 4096 / 2
)
var (
	errNegativeRead = errors.New("reader returned negative count from Read")
)
type Lexer struct {
	buf          []byte
	rd           io.Reader  
	r            int        
	lastByte     int        
	lastRuneSize []int      
	err          error
}
const maxConsecutiveEmptyReads = 100
func NewLexer(rd io.Reader) *Lexer {
	p := Lexer{}
	p.rd = rd
	p.lastByte = bufSize
	p.buf = make([]byte, bufSize)
	p.r = -1
	p.fill()
	return &p
}
func (p *Lexer) fill() {
	if p.r >= 0 && p.r < bufSize {
		return
	}
	offset := 0
	if p.r >= 0 {
		copy(p.buf, p.buf[halfSize:])
		p.r = halfSize
		offset = halfSize
	} else {
		p.r = 0
	}
	for i := maxConsecutiveEmptyReads; i > 0; i-- {
		n, err := p.rd.Read(p.buf[offset:])
		if n < 0 {
			panic(errNegativeRead)
		}
		if err != nil {
			p.err = err
			break
		}
		offset += n
		if offset >= halfSize {
			break
		}
	}
	p.lastByte = offset
}
func (p *Lexer) Error() error {
	err := p.err
	p.err = nil
	return err
}
func (p *Lexer) PeekByte() byte {
	c, err := p.Byte()
	if err != nil {
		return 0
	}
	p.UnreadByte()
	return c
}
func (p *Lexer) PeekRune() (rune, error) {
	r, err := p.Rune()
	if err != nil {
		return 0, nil
	}
	return r, p.UnreadRune()
}
func (p *Lexer) Byte() (byte, error) {
	if p.lastByte < bufSize && p.r >= p.lastByte {
		p.r = p.lastByte + 1
		return 0, ErrEOS
	}
	c := p.buf[p.r]
	p.r++
	p.fill()
	return c, nil
}
func (p *Lexer) UnreadByte() {
	if p.r <= 0 {
		return
	}
	p.r--
}
func (p *Lexer) Rune() (rune, error) {
	p.fill()
	r, size := rune(p.buf[p.r]), 1
	if r >= utf8.RuneSelf {
		r, size = utf8.DecodeRune(p.buf[p.r:p.lastByte])
	}
	p.r += size
	p.lastRuneSize = append(p.lastRuneSize, size)
	return r, nil
}
func (p *Lexer) UnreadRune() error {
	if len(p.lastRuneSize) == 0 {
		return ErrInvalidUnread
	}
	p.r -= p.lastRuneSize[len(p.lastRuneSize)-1]
	p.lastRuneSize = p.lastRuneSize[:len(p.lastRuneSize)-1]
	return nil
}
func (p *Lexer) String() (string, bool) {
	var buf []byte
	for {
		c, _ := p.Byte()
		if !IsTextChar(c) {
			break
		}
		buf = append(buf, c)
	}
	p.UnreadByte()
	return string(buf), len(buf) > 0
}
func (p *Lexer) StringStop(stopBytes []byte) (string, bool) {
	var buf []byte
	for {
		c, _ := p.Byte()
		if !IsTextChar(c) || bytes.IndexByte(stopBytes, c) != -1 {
			break
		}
		buf = append(buf, c)
	}
	p.UnreadByte()
	return string(buf), len(buf) > 0
}
func (p *Lexer) Break() bool {
	c, _ := p.Byte()
	if c == '\r' {
		c, _ = p.Byte()
	}
	if c == '\n' {
		return true
	}
	p.UnreadByte()
	return false
}
func (p *Lexer) End() bool {
	c, err := p.Byte()
	if err != nil {
		return true
	}
	if IsEndChar(c) {
		return true
	}
	p.UnreadByte()
	return false
}
func (p *Lexer) WhiteSpace() bool {
	any := false
	for {
		c, _ := p.Byte()
		if c != 13 && c != 10 && c != 9 && c != 32 {
			break
		}
		any = true
	}
	p.UnreadByte()
	return any
}
func (p *Lexer) Space() (int, byte) {
	n := 0
	m := 0
	for {
		c, _ := p.Byte()
		if c != '\t' && c != ' ' {
			break
		}
		if c == ' ' {
			n++
		} else {
			m++
		}
	}
	p.UnreadByte()
	var r byte
	if m == 0 {
		r = ' '
	} else if n == 0 {
		r = '\t'
	}
	return n + m, r
}
func (p *Lexer) Quoted(ind int) (string, bool, error) {
	c1, _ := p.Byte()
	if c1 != '"' && c1 != '\'' && c1 != '`' {
		p.UnreadByte()
		return "", false, nil
	}
	var buf []byte
	var c2 byte
	for {
		c, _ := p.Byte()
		if IsEndChar(c) {
			return "", false, ErrUnterminatedQuotedString
		}
		if c == c1 && c1 == '`' {
			break
		}
		if c == c1 && c2 != '\\' {
			break
		}
		if c1 != '`' {
			if c == '\\' {
				c2 = c
				continue
			}
			if c2 == '\\' && !(c != '\'' || c == '"') {
				buf = append(buf, '\\')
			}
		}
		buf = append(buf, c)
		if c == 10 {
			n, u := p.Space()
			if u == 0 {
				return "", false, ErrSpaceNotUniform
			}
			for ; n-ind > 0; n-- {
				buf = append(buf, u)
			}
		}
		c2 = c
	}
	return string(buf), true, nil
}
func (p *Lexer) Token8() (string, bool) {
	var buf []rune
	for {
		c, _ := p.Rune()
		if !isTokenChar(c) {
			break
		}
		buf = append(buf, c)
	}
	p.UnreadRune()
	return string(buf), len(buf) > 0
}
func (p *Lexer) Integer() (string, bool) {
	var buf []byte
	for {
		c, _ := p.Byte()
		if !IsDigit(rune(c)) {
			break
		}
		buf = append(buf, c)
	}
	p.UnreadByte()
	return string(buf), len(buf) > 0
}
func (p *Lexer) Number() (string, bool) {
	var buf []byte
	var sign byte
	point := false
	c := p.PeekByte()
	if c == '-' || c == '+' {
		sign = c
		p.Byte()
	}
	for {
		c, _ := p.Byte()
		if !IsDigit(rune(c)) {
			if !point && c == '.' {
				point = true
				buf = append(buf, c)
				continue
			}
			break
		}
		buf = append(buf, c)
	}
	p.UnreadByte()
	if sign == '-' {
		return "-" + string(buf), len(buf) > 0
	}
	return string(buf), len(buf) > 0
}
func (p *Lexer) Operator() (string, bool) {
	var buf []byte
	for {
		c, _ := p.Byte()
		if !isOperatorChar(c) {
			break
		}
		buf = append(buf, c)
	}
	p.UnreadByte()
	return string(buf), len(buf) > 0
}
func (p *Lexer) TemplateText() (string, bool) {
	var buf []byte
	for {
		c, _ := p.Byte()
		if !isTemplateTextChar(c) {
			break
		}
		buf = append(buf, c)
	}
	p.UnreadByte()
	return string(buf), len(buf) > 0
}
func (p *Lexer) Comment() bool {
	c, _ := p.Byte()
	if c == '#' {
		c, _ = p.Byte()
		if IsSpaceChar(c) {
			for {
				c, _ = p.Byte()
				if IsEndChar(c) || IsBreakChar(c) {
					break
				}
			}
			return true
		}
		p.UnreadByte()
	}
	p.UnreadByte()
	return false
}
func (p *Lexer) Block(nsp int) (string, bool) {
	c, _ := p.Byte()
	if c != '\\' {
		p.UnreadByte()
		return "", false
	}
	c, _ = p.Byte()
	if c != 10 && c != 13 {
		p.UnreadByte()
		p.UnreadByte()
		return "", false
	}
	if c == 13 {
		p.Byte()
	}
	buffer := &bytes.Buffer{}
	for {
		ns, u := p.Space()
		if u == 0 || ns <= nsp {
			break
		}
		for {
			c, _ = p.Byte()
			if IsEndChar(c) {
				break
			}
			if c == 13 {
				continue
			}
			buffer.WriteByte(c)
			if c == 10 {
				break
			}
		}
	}
	s := buffer.String()
	for {
		if len(s) == 0 {
			break
		}
		c := s[len(s)-1]
		if c == 10 {
			s = s[0 : len(s)-1]
		} else {
			break
		}
	}
	return s, true
}
func (p *Lexer) Scalar(n int) (string, bool) {
	b, ok, _ := p.Quoted(n)
	if ok {
		return b, true
	}
	return p.String()
}
func (p *Lexer) ScalarType(n int) (interface{}, bool) {
	b, ok, _ := p.Quoted(n)
	if ok {
		return b, true
	}
	s, ok := p.String()
	if !ok {
		return "", false
	}
	i, err := strconv.ParseInt(s, 10, 64)
	if err == nil {
		return i, true
	}
	f, err := strconv.ParseFloat(s, 64)
	if err == nil {
		return f, true
	}
	switch s {
	case "true":
		return true, true
	case "false":
		return false, true
	default:
		return s, true
	}
}
func IsTextChar(c byte) bool {
	return c > 32
}
func IsEndChar(c byte) bool {
	return c < 32 && c != '\t' && c != '\n' && c != '\r'
}
func IsEndRune(c rune) bool {
	return c < 32 && c != '\t' && c != '\n' && c != '\r'
}
func IsBreakChar(c byte) bool {
	return c == 10 || c == 13
}
func IsSpaceChar(c byte) bool {
	return c == 32 || c == 9
}