func (s *State) SaveVars(cs, ts, te, act int) {
	s.cs, s.ts, s.te, s.act = cs, ts, te, act
}
SaveVars saves the ragel state variables. These variables must be saved
between calls to Interface.Run, so SaveVars must be called before returning
from Interface.Run and Interface.Init.
package ragel
import (
	"fmt"
	"io"
	"unicode/utf8"
)
const DefaultBufferSize = 32768
type Interface interface {
	Init(s *State) (start, err int)
	Run(s *State, p, pe, eof int) (np, npe int)
}
type queue struct {
	items []item
	head  int
	tail  int
	count int
}
func (q *queue) push(i item) {
	if q.items == nil {
		q.items = make([]item, 2)
	}
	if q.head == q.tail && q.count > 0 {
		items := make([]item, len(q.items)*2)
		copy(items, q.items[q.head:])
		copy(items[len(q.items)-q.head:], q.items[:q.head])
		q.head = 0
		q.tail = len(q.items)
		q.items = items
	}
	q.items[q.tail] = i
	q.tail = (q.tail + 1) % len(q.items)
	q.count++
}
func (q *queue) pop() (int, Token, string) {
	i := q.head
	q.head = (q.head + 1) % len(q.items)
	q.count--
	pi := &q.items[i]
	return pi.off, pi.tok, pi.lit
}
type Token int
const (
	EOF Token = -1 - iota
	Error
)
type item struct {
	off int
	tok Token
	lit string
}
type Option interface {
	set(*state)
}
type optionFn func(*state)
func (f optionFn) set(s *state) { f(s) }
func BufferSize(size int) Option {
	return optionFn(func(s *state) {
		s.bufferSize = size
	})
}
type Scanner state
type State state
type state struct {
	queue
	fileName   string
	r          io.Reader
	offset     int
	lines      []int
	iface      Interface
	bufferSize int
	cs, ts, te, act int     
	data            []byte  
	ss, se          int     
	sz              int     
	abort bool
}
func New(fileName string, r io.Reader, iface Interface, opts ...Option) *Scanner {
	s := &state{
		r:          r,
		fileName:   fileName,
		lines:      []int{0},
		iface:      iface,
		bufferSize: DefaultBufferSize,
	}
	for _, o := range opts {
		o.set(s)
	}
	s.data = make([]byte, s.bufferSize)
	s.ss, s.se = iface.Init((*State)(s))
	return (*Scanner)(s)
}
func (s *Scanner) Reset(opts ...Option) {
	s.queue.count = 0
	s.queue.head = 0
	s.queue.tail = 0
	s.abort = false
	s.offset = 0
	s.lines = s.lines[:1]
	s.sz = 0
	r := s.r.(io.Seeker)
	_, err := r.Seek(0, io.SeekStart)
	if err != nil {
		panic(err)
	}
	s.ss, s.se = s.iface.Init((*State)(s))
	for _, o := range opts {
		o.set((*state)(s))
	}
	if len(s.data) != s.bufferSize {
		s.data = make([]byte, s.bufferSize)
	}
}
func (s *Scanner) Next() (offset int, token Token, literal string) {
	for s.count == 0 && !s.abort {
		var (
			n, p, pe, eof int
			err           error
		)
		p = s.sz
		if p < len(s.data) {
			for {
				n, err = s.r.Read(s.data[p:])
				if n != 0 || err != nil {
					break
				}
			}
			pe = p + n
			eof = -1
			if err != nil {
				eof = pe
			}
		} else {
			n, err = s.r.Read([]byte{0})
			if err == nil || n > 0 {
				(*State)(s).Errorf(0, true, "token too long")
				break
			}
			pe, eof = p, p
		}
	again:
		p, pe = s.iface.Run((*State)(s), p, pe, eof)
		switch s.cs {
		case s.se:
			r, rs := utf8.DecodeRune(s.data[p:pe])
			if r == utf8.RuneError {
				r = rune(s.data[p])
			}
			(*State)(s).Errorf(p, false, "invalid character %#U", r)
			p += rs
			s.cs = s.ss
			if p < pe {
				goto again
			}
			fallthrough
		case s.ss:
			s.sz = 0
			s.offset += p
		default:
			if s.ts > 0 {
				s.offset += s.ts
				s.sz = pe - s.ts
				copy(s.data[:], s.data[s.ts:pe])
				s.te -= s.ts
				s.ts = 0
			} else {
				s.sz = pe
			}
		}
		if err != nil {
			s.abort = true
			if err != io.EOF {
				(*State)(s).Errorf(s.sz, true, err.Error())
			} else if s.cs != s.ss {
				(*State)(s).Errorf(0, true, "non-terminated token: unexpected EOF")
			}
			s.offset += s.sz
		}
	}
	if s.count > 0 {
		return s.pop()
	}
	return s.offset, EOF, "EOF"
}