/*
This file is used with golex to generate a lexer that has a signature compatible with goyacc.
Many constants referred to below are defined by goyacc when creating template.y.go
See https://godoc.org/modernc.org/golex for more about golex
*/
%{
package datemath
import (
"bytes"
"fmt"
"strconv"
)
const (
// 0 is expected by the goyacc generated parser to indicate EOF
eofCode = 0
)
// lexer holds the state of the lexer
type lexer struct {
src *bytes.Reader
buf []byte
current byte
pos int
errors []string
}
func newLexer(b []byte) *lexer {
l := &lexer{
src: bytes.NewReader(b),
}
// queue up a byte
l.next()
return l
}
func (l *lexer) Error(s string) {
l.errors = append(l.errors, fmt.Sprintf("%s at character %d starting with %q", s, l.pos, string(l.buf)))
}
func (l *lexer) next() {
if l.current != 0 {
l.buf = append(l.buf, l.current)
}
l.current = 0
if b, err := l.src.ReadByte(); err == nil {
l.current = b
}
l.pos++
}
func (l *lexer) Lex(lval *yySymType) int {
%}
/* give some regular expressions more semantic names for use below */
eof \0
/* tell golex how to determine the current start condition */
%yyt l.startCondition
/* tell golex how to determine the current byte */
%yyc l.current
/* tell golex how to advance to the next byte */
%yyn l.next()
%%
// runs before each token is parsed
l.buf = l.buf[:0]
[0-9]
i, err := strconv.ParseInt(string(l.buf), 10, 0)
if err != nil {
panic(fmt.Sprintf("could not parse digit as number: %s", err))
}
lval.i = int(i)
return tDIGIT
"now"
return tNOW
"+"
return tPLUS
"-"
return tMINUS
":"
return tCOLON
"||"
return tPIPES
"/"
return tBACKSLASH
[yMwdbhHms]
switch l.buf[0] {
case 'y':
lval.unit = timeUnitYear
case 'M':
lval.unit = timeUnitMonth
case 'w':
lval.unit = timeUnitWeek
case 'b':
lval.unit = timeUnitBusinessDay
case 'd':
lval.unit = timeUnitDay
case 'h', 'H':
lval.unit = timeUnitHour
case 'm':
lval.unit = timeUnitMinute
case 's':
lval.unit = timeUnitSecond
default:
panic(fmt.Sprintf("unknown time unit: %q", l.buf[0]))
}
return tUNIT
\.
return tDOT
"T"
return tTIME_DELIMITER
"Z"
return tUTC
{eof}
return eofCode
.
return tINVALID_TOKEN
%%
// should never get here
panic("scanner internal error")
}