You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
dorm/vendor/modernc.org/ql/lexer.go

173 lines
3.0 KiB

// Copyright 2017 The ql Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package ql // import "modernc.org/ql"
import (
"fmt"
"go/scanner"
"go/token"
"math"
"strconv"
"strings"
"unicode"
"modernc.org/golex/lex"
)
const (
ccEOF = iota + 0x80
ccLetter
ccDigit
ccOther
ccOGuill
ccCGuill
)
func runeClass(r rune) int {
switch {
case r == lex.RuneEOF:
return ccEOF
case r < 0x80:
return int(r)
case unicode.IsLetter(r):
return ccLetter
case unicode.IsDigit(r):
return ccDigit
case r == '«':
return ccOGuill
case r == '»':
return ccCGuill
default:
return ccOther
}
}
type lexer struct {
*lex.Lexer
agg []bool
col int
errs scanner.ErrorList
expr expression
file *token.File
inj int
line int
list []stmt
params int
root bool
sc int
}
func newLexer(src string) (*lexer, error) {
fset := token.NewFileSet()
file := fset.AddFile("", -1, len(src))
l := &lexer{
file: file,
}
l0, err := lex.New(
file,
strings.NewReader(src),
lex.ErrorFunc(func(pos token.Pos, msg string) {
l.errPos(pos, msg)
}),
lex.RuneClass(runeClass),
lex.BOMMode(lex.BOMIgnoreFirst),
)
if err != nil {
return nil, err
}
l.Lexer = l0
return l, nil
}
func (l *lexer) errPos(pos token.Pos, format string, arg ...interface{}) {
l.errs.Add(l.file.Position(pos), fmt.Sprintf(format, arg...))
}
func (l *lexer) err(s string, arg ...interface{}) {
l.errPos(l.Last.Pos(), s, arg...)
}
// Implements yyLexer.
func (l *lexer) Error(s string) {
l.err(s)
}
func (l *lexer) int(lval *yySymType, im bool) int {
val := l.TokenBytes(nil)
if im {
val = val[:len(val)-1]
}
n, err := strconv.ParseUint(string(val), 0, 64)
if err != nil {
l.err("integer literal: %v", err)
return int(unicode.ReplacementChar)
}
if im {
lval.item = idealComplex(complex(0, float64(n)))
return imaginaryLit
}
switch {
case n < math.MaxInt64:
lval.item = idealInt(n)
default:
lval.item = idealUint(n)
}
return intLit
}
func (l *lexer) float(lval *yySymType, im bool) int {
val := l.TokenBytes(nil)
if im {
val = val[:len(val)-1]
}
n, err := strconv.ParseFloat(string(val), 64)
if err != nil {
l.err("float literal: %v", err)
return int(unicode.ReplacementChar)
}
if im {
lval.item = idealComplex(complex(0, n))
return imaginaryLit
}
lval.item = idealFloat(n)
return floatLit
}
func (l *lexer) str(lval *yySymType, pref string) int {
val := l.TokenBytes(nil)
l.sc = 0
s := pref + string(val)
s, err := strconv.Unquote(s)
if err != nil {
l.err("string literal: %v", err)
return int(unicode.ReplacementChar)
}
lval.item = s
return stringLit
}
func (l *lexer) delimitedIdentifier(lval *yySymType) int {
val := l.TokenBytes(nil)
l.sc = 0
if len(val) < 5 {
l.err("quotedIdentifier too short: %v", val)
return int(unicode.ReplacementChar)
}
s := string(val[2:(len(val) - 2)])
lval.item = s
return identifier
}
func (l *lexer) npos() (line, col int) {
pos := l.file.Position(l.Last.Pos())
return pos.Line, pos.Column
}