Exemple #1
0
// StringToVersion function parses a string into a Version struct which can be compared
//
// The implementation is based on http://man.he.net/man5/deb-version
// on https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Version
//
// It uses the dpkg-1.17.25's algorithm  (lib/parsehelp.c)
func StringToVersion(str string) (Version, error) {
	var version Version

	// Trim leading and trailing space
	str = strings.TrimSpace(str)

	if len(str) <= 0 {
		return Version{}, errors.New("Version string is empty")
	}

	// Find Epoch
	sepEpoch := strings.Index(str, ":")
	if sepEpoch > -1 {
		intEpoch, err := strconv.Atoi(str[:sepEpoch])
		if err == nil {
			version.Epoch = intEpoch
		} else {
			return Version{}, errors.New("Epoch in version is not a number")
		}
		if intEpoch < 0 {
			return Version{}, errors.New("Epoch in version is negative")
		}
	} else {
		version.Epoch = 0
	}

	// Find UpstreamVersion / DebianRevision
	sepDebianRevision := strings.LastIndex(str, "-")
	if sepDebianRevision > -1 {
		version.UpstreamVersion = str[sepEpoch+1 : sepDebianRevision]
		version.DebianRevision = str[sepDebianRevision+1:]
	} else {
		version.UpstreamVersion = str[sepEpoch+1:]
		version.DebianRevision = "0"
	}
	// Verify format
	if len(version.UpstreamVersion) == 0 {
		return Version{}, errors.New("No UpstreamVersion in version")
	}

	if !unicode.IsDigit(rune(version.UpstreamVersion[0])) {
		return Version{}, errors.New("UpstreamVersion in version does not start with digit")
	}

	for i := 0; i < len(version.UpstreamVersion); i = i + 1 {
		r := rune(version.UpstreamVersion[i])
		if !unicode.IsDigit(r) && !unicode.IsLetter(r) && !containsRune(upstreamVersionAllowedSymbols, r) {
			return Version{}, errors.New("invalid character in UpstreamVersion")
		}
	}

	for i := 0; i < len(version.DebianRevision); i = i + 1 {
		r := rune(version.DebianRevision[i])
		if !unicode.IsDigit(r) && !unicode.IsLetter(r) && !containsRune(debianRevisionAllowedSymbols, r) {
			return Version{}, errors.New("invalid character in DebianRevision")
		}
	}

	return version, nil
}
Exemple #2
0
/*
StringTrimNonAlnum remove non alpha-numeric character at the beginning and end
for `text`.
*/
func StringTrimNonAlnum(text string) string {
	r := []rune(text)
	rlen := len(r)
	start := 0

	for ; start < rlen; start++ {
		if unicode.IsLetter(r[start]) || unicode.IsDigit(r[start]) {
			break
		}
	}

	if start >= rlen {
		return ""
	}

	r = r[start:]
	rlen = len(r)
	end := rlen - 1
	for ; end >= 0; end-- {
		if unicode.IsLetter(r[end]) || unicode.IsDigit(r[end]) {
			break
		}
	}

	if end < 0 {
		return ""
	}

	r = r[:end+1]

	return string(r)
}
Exemple #3
0
func readIdentifier(r *kmgGoReader.Reader) []byte {
	buf := &bytes.Buffer{}
	if r.IsEof() {
		panic(r.GetFileLineInfo() + " unexcept EOF")
	}
	b := r.ReadRune()
	if b == '_' || unicode.IsLetter(b) {
		buf.WriteRune(b)
	} else {
		r.UnreadRune()
		return nil
	}
	for {
		if r.IsEof() {
			return buf.Bytes()
		}
		b := r.ReadRune()
		if b == '_' || unicode.IsLetter(b) || unicode.IsDigit(b) {
			buf.WriteRune(b)
		} else {
			r.UnreadRune()
			return buf.Bytes() // 不是Identifier的东西留个调用者处理
		}
	}
}
Exemple #4
0
func CheckRuneType(last, current rune) index.RuneType {
	if isTermSep(current) {
		return index.TokenSep
	}

	if current > 128 {
		return index.TokenStart
	}

	if unicode.IsLetter(current) {
		if unicode.IsLetter(last) {
			return index.TokenBody
		}
		return index.TokenStart
	}

	if unicode.IsNumber(current) {
		if unicode.IsNumber(last) {
			return index.TokenBody
		}
		return index.TokenStart
	}

	return index.TokenStart
}
// FmtFieldName formats a string as a struct key
//
// Example:
// 	FmtFieldName("foo_id")
// Output: FooID
func FmtFieldName(s string) string {
	runes := []rune(s)
	for len(runes) > 0 && !unicode.IsLetter(runes[0]) && !unicode.IsDigit(runes[0]) {
		runes = runes[1:]
	}
	if len(runes) == 0 {
		return "_"
	}

	s = stringifyFirstChar(string(runes))
	name := lintFieldName(s)
	runes = []rune(name)
	for i, c := range runes {
		ok := unicode.IsLetter(c) || unicode.IsDigit(c)
		if i == 0 {
			ok = unicode.IsLetter(c)
		}
		if !ok {
			runes[i] = '_'
		}
	}
	s = string(runes)
	s = strings.Trim(s, "_")
	if len(s) == 0 {
		return "_"
	}
	return s
}
Exemple #6
0
/**
CSS time unit

@see https://developer.mozilla.org/zh-TW/docs/Web/CSS/time
*/
func lexNumberUnit(l *Lexer) stateFn {
	tok := l.matchKeywordList(ast.UnitTokenList)

	if tok == nil {
		var r = l.next()

		// for an+b syntax
		if r == 'n' && !unicode.IsLetter(l.peek()) {

			l.emit(ast.T_N)

		} else {

			// for other unit tokens
			for unicode.IsLetter(r) {
				r = l.next()
			}
			l.backup()
			if l.length() > 0 {
				l.emit(ast.T_UNIT_OTHERS)
			}

		}
	}

	if l.peek() == ';' {
		return lexStmt
	}
	return lexExpr
}
Exemple #7
0
func validPackageNames(name string) error {
	if len(name) < 1 {
		return fmt.Errorf(errInvalidPackage, "the name can't be blank")
	}

	for i, r := range []rune(name) {
		if i == 0 {
			if !unicode.IsLetter(r) {
				return fmt.Errorf(errInvalidPackage, "the first character must be a letter")
			}
		}

		switch {
		case unicode.IsLetter(r):
		case unicode.IsDigit(r):
		case r == '-':
		case r == '_':
		case r == '.':
			// ok
		default:
			return fmt.Errorf(errInvalidPackage, "all the characters (but the first) must be either letters or digits")
		}
	}

	return nil
}
Exemple #8
0
func lexTypeSelector(l *Lexer) stateFn {
	var r = l.next()
	if !unicode.IsLetter(r) && !IsInterpolationStartToken(r, l.peekBy(2)) {
		l.error("Expecting letter token for tag name selector. got %s", r)
	}

	var foundInterpolation = false
	r = l.next()
	for {
		if IsInterpolationStartToken(r, l.peek()) {
			l.backup()
			lexInterpolation(l, false)
			foundInterpolation = true
		} else if !unicode.IsLetter(r) && !unicode.IsDigit(r) {
			break
		}
		r = l.next()
	}
	l.backup()

	if foundInterpolation {
		l.emit(ast.T_INTERPOLATION_SELECTOR)
	} else {
		l.emit(ast.T_TYPE_SELECTOR)
	}

	return lexSimpleSelector
}
Exemple #9
0
func lexLang(l *Lexer) stateFn {
	/*
		html:lang(fr-ca) { quotes: '« ' ' »' }
		html:lang(de) { quotes: '»' '«' '\2039' '\203A' }
		:lang(fr) > Q { quotes: '« ' ' »' }
		:lang(de) > Q { quotes: '»' '«' '\2039' '\203A' }
	*/
	// [a-z]{2} - [a-z]{2}
	// [a-z]{2}
	var r = l.next()
	if !unicode.IsLetter(r) {
		l.error("Unexpected language token. Got '%s'", r)
	}

	r = l.next()
	if !unicode.IsLetter(r) {
		l.error("Unexpected language token. Got '%s'", r)
	}

	r = l.peek()
	if r == '-' {
		l.next() // skip '-'
		r = l.next()
		if !unicode.IsLetter(r) {
			l.error("Unexpected language token. Got '%s'", r)
		}
		r = l.next()
		if !unicode.IsLetter(r) {
			l.error("Unexpected language token. Got '%s'", r)
		}
	}
	l.emit(ast.T_LANG_CODE)
	return nil
}
Exemple #10
0
func lexIdentifier(l *Lexer) stateFn {
	var r = l.next()
	if !unicode.IsLetter(r) && r != '-' {
		panic("An identifier needs to start with a letter or dash")
	}
	r = l.next()

	for unicode.IsLetter(r) || unicode.IsDigit(r) || r == '-' {
		if r == '-' {
			var r2 = l.peek()
			if !unicode.IsLetter(r2) && r2 != '-' {
				l.backup()
				return lexExpr
			}
		}

		r = l.next()
	}
	l.backup()

	if l.peek() == '(' {
		var curTok = l.emit(ast.T_FUNCTION_NAME)

		if curTok.Str == "url" || curTok.Str == "local" {
			lexUrlParam(l)
		} else {
			lexFunctionParams(l)
		}
	} else {
		l.emit(ast.T_IDENT)
	}
	return lexExpr
}
Exemple #11
0
func ConvertToUnderscore(camel string) (string, error) {
	var prevRune rune
	var underscore []rune
	for index, runeChar := range camel {
		if index == 0 {
			if !unicode.IsLetter(runeChar) {
				return "", fmt.Errorf("Table and column names can't start with a character other than a letter.")
			}
			underscore = append(underscore, unicode.ToLower(runeChar))
			prevRune = runeChar
		} else {
			if runeChar == '_' || unicode.IsLetter(runeChar) || unicode.IsDigit(runeChar) {
				//Look for Upper case letters, append _ and make character lower case
				if unicode.IsUpper(runeChar) {
					if !unicode.IsUpper(prevRune) {
						underscore = append(underscore, '_')
					}
					underscore = append(underscore, unicode.ToLower(runeChar))
				} else {
					underscore = append(underscore, runeChar)
				}
			} else {
				return "", fmt.Errorf("Table and column names can't contain non-alphanumeric characters.")
			}
		}
		prevRune = runeChar
	}
	return string(underscore), nil
}
Exemple #12
0
Fichier : sc.go Projet : kpmy/lomo
func (s *sc) ident() (sym Sym) {
	assert.For(unicode.IsLetter(s.ch), 20, "character expected")
	var buf []rune
	for {
		buf = append(buf, s.ch)
		s.next()
		if s.err != nil || !(unicode.IsLetter(s.ch) || unicode.IsDigit(s.ch)) {
			break
		}
	}
	if s.err == nil {
		sym.Str = string(buf)
		key := sym.Str
		if s.evil == nil {
			x := true
			s.evil = &x
			if keyTab[key] == None && keyTab[strings.ToUpper(key)] == s.useTab[0] {
				*s.evil = true
			} else if keyTab[key] == s.useTab[0] {
				*s.evil = false
			}
		}
		set := func() {
			if sym.Code = keyTab[key]; sym.Code == None {
				sym.Code = Ident
				sym.User = s.foreignTab[key]
			} else if sym.Code != None {
				ok := false
				for _, u := range s.useTab {
					if u == sym.Code {
						ok = true
						break
					}
				}
				if !ok {
					sym.Code = Ident
					sym.User = s.foreignTab[key]
				}
			}
		}
		if s.evil != nil {
			if *s.evil {
				key = strings.ToUpper(sym.Str)
				if key != sym.Str {
					set()
				} else {
					sym.Code = Ident
				}
			} else {
				set()
			}

		} else {
			sym.Code = Ident
		}
	} else {
		s.mark("error while ident read")
	}
	return
}
Exemple #13
0
//Atbash implements atbash cypher
func Atbash(s string) (cypher string) {
	s = strings.ToLower(s)
	// s = strings.Replace(s, " ", "", -1)
	var code []string
	var block int
	for _, v := range s {
		if unicode.IsLetter(v) || unicode.IsNumber(v) {
			if block == 5 {
				code = append(code, DELIMITER)
				block = 0
			}

			if unicode.IsLetter(v) {
				index := v - 'a'
				cypherIndex := (('z' - 'a') - index)
				code = append(code, string(cypherIndex+'a'))
			} else {
				code = append(code, string(v))

			}

			block++
		}
	}
	cypher = strings.Join(code, "")
	return
}
Exemple #14
0
// our simplified version of MapReduce does not supply a
// key to the Map function, as in the paper; only a value,
// which is a part of the input file content. the return
// value should be a list of key/value pairs, each represented
// by a mapreduce.KeyValue.
func Map(value string) *list.List {
	//content := []string{}
	content := make(map[string]int)
	valueLen := len(value)
	index := 0
	for index < valueLen {
		for index < valueLen && !unicode.IsLetter(rune(value[index])) {
			index++
		}
		start := index
		for index < valueLen && unicode.IsLetter(rune(value[index])) {
			index++
		}
		//		content = append(content, value[start:index])
		content[value[start:index]]++
	}
	l := list.New()
	//	for _, word := range content {
	//		l.PushBack(mapreduce.KeyValue{word, "1"})
	//	}
	for k, v := range content {
		l.PushBack(mapreduce.KeyValue{k, strconv.Itoa(v)})
	}
	return l
}
Exemple #15
0
// extractLetterSequence extracts first word (sequence of letters ending with a non-letter)
// starting with the specified index and wraps it to dateStringLayoutItem according to the type
// of the word.
func extractLetterSequence(originalStr string, index int) (it dateStringLayoutItem) {
	letters := ""

	bytesToParse := []byte(originalStr[index:])
	runeCount := utf8.RuneCount(bytesToParse)

	var isWord bool
	var isDigit bool

	for i := 0; i < runeCount; i++ {
		rune, runeSize := utf8.DecodeRune(bytesToParse)
		bytesToParse = bytesToParse[runeSize:]

		if i == 0 {
			isWord = unicode.IsLetter(rune)
			isDigit = unicode.IsDigit(rune)
		} else {
			if (isWord && (!unicode.IsLetter(rune) && !unicode.IsDigit(rune))) ||
				(isDigit && !unicode.IsDigit(rune)) ||
				(!isWord && unicode.IsLetter(rune)) ||
				(!isDigit && unicode.IsDigit(rune)) {
				break
			}
		}

		letters += string(rune)
	}

	it.item = letters
	it.isWord = isWord
	it.isDigit = isDigit

	return
}
Exemple #16
0
func lexIdSelector(l *Lexer) stateFn {
	var foundInterpolation = false
	var r = l.next()
	r = l.next()
	if !unicode.IsLetter(r) && r != '#' && l.peek() != '{' {
		l.error("An identifier should start with at least a letter, Got '%s'", r)
	}
	for {
		if IsInterpolationStartToken(r, l.peek()) {
			l.backup()
			lexInterpolation(l, false)
			foundInterpolation = true
		} else if !unicode.IsLetter(r) && !unicode.IsDigit(r) {
			break
		}
		r = l.next()
	}
	l.backup()

	r = l.next()
	for unicode.IsLetter(r) || unicode.IsDigit(r) {
		r = l.next()
	}
	l.backup()

	if foundInterpolation {
		l.emit(ast.T_INTERPOLATION_SELECTOR)
	} else {
		l.emit(ast.T_ID_SELECTOR)
	}
	return lexSelectors
}
func (lexer *Lexer) nextId(ch byte) *Id {
	state := 9
	for {
		switch state {
		case 9:
			if unicode.IsLetter(rune(ch)) {
				state = 10
				ch, _ = lexer.df.nextChar()
			} else {
				log.Fatalln("Lexer::nextId(): invalid input", ch, "and current state is", state)
			}
		case 10:
			if unicode.IsLetter(rune(ch)) || unicode.IsDigit(rune(ch)) {
				state = 10
				ch, _ = lexer.df.nextChar()
			} else {
				state = 11
			}
		case 11:
			lexeme := lexer.df.nextLexeme()
			if id, ok := lexer.words[lexeme]; ok {
				return id.(*Id)
			}
			id := newId(REST, lexeme)
			lexer.words[lexeme] = id
			return id
		}
	}
}
Exemple #18
0
// parseVariable consumes the variable name including the closing curly brace.
//
// The opening curly brace was already consumed when this method is called.
func (p *parser) parseVariable() error {
	switch r := p.next(); {
	case r == eof:
		return p.errorf("unexpected eof after '{'")
	case r == '*':
		if r = p.next(); r != '}' {
			return p.errorf("expected '}' after '*'")
		}
		if r = p.next(); r != eof {
			return p.errorf("expected eof after '{*}'")
		}
		return nil
	case r != '_' && !unicode.IsLetter(r):
		return p.errorf("expected underscore or letter starting a variable name; got %q", r)
	}
	for {
		switch r := p.next(); {
		case r == '}':
			return nil
		case r == eof:
			return p.errorf("unexpected eof in variable name")
		case r == p.sep:
			return p.errorf("missing '}' in variable declaration")
		case r != '_' && !unicode.IsLetter(r) && !unicode.IsDigit(r):
			return p.errorf("unexpected %q in variable name", r)
		}
	}
}
Exemple #19
0
func norm(input []rune) []rune {

	inputLen := len(input)
	if inputLen > 4 {
		for i := 0; i < inputLen; i++ {
			switch input[i] {
			case 'à', 'á', 'â':
				input[i] = 'a'
			case 'ô':
				input[i] = 'o'
			case 'è', 'é', 'ê':
				input[i] = 'e'
			case 'ù', 'û':
				input[i] = 'u'
			case 'î':
				input[i] = 'i'
			case 'ç':
				input[i] = 'c'
			}

			ch := input[0]
			for i := 1; i < inputLen; i++ {
				if input[i] == ch && unicode.IsLetter(ch) {
					input = analysis.DeleteRune(input, i)
					i -= 1
					inputLen = len(input)
				} else {
					ch = input[i]
				}
			}
		}
	}

	if inputLen > 4 && analysis.RunesEndsWith(input, "ie") {
		input = input[0 : inputLen-2]
		inputLen = len(input)
	}

	if inputLen > 4 {
		if input[inputLen-1] == 'r' {
			input = input[0 : inputLen-1]
			inputLen = len(input)
		}
		if input[inputLen-1] == 'e' {
			input = input[0 : inputLen-1]
			inputLen = len(input)
		}
		if input[inputLen-1] == 'e' {
			input = input[0 : inputLen-1]
			inputLen = len(input)
		}
		if input[inputLen-1] == input[inputLen-2] && unicode.IsLetter(input[inputLen-1]) {
			input = input[0 : inputLen-1]
			inputLen = len(input)
		}
	}

	return input
}
Exemple #20
0
func (c *Cursor) AtEow() bool {
	r, _ := c.RuneAfter()
	rb, _ := c.RuneBefore()
	if !(unicode.IsLetter(r) || unicode.IsDigit(r)) && (unicode.IsLetter(rb) || unicode.IsDigit(rb)) {
		return true
	}
	return false
}
Exemple #21
0
func (l keyList) Less(i, j int) bool {
	a := l[i]
	b := l[j]
	ak := a.Kind()
	bk := b.Kind()
	for (ak == reflect.Interface || ak == reflect.Ptr) && !a.IsNil() {
		a = a.Elem()
		ak = a.Kind()
	}
	for (bk == reflect.Interface || bk == reflect.Ptr) && !b.IsNil() {
		b = b.Elem()
		bk = b.Kind()
	}
	af, aok := keyFloat(a)
	bf, bok := keyFloat(b)
	if aok && bok {
		if af != bf {
			return af < bf
		}
		if ak != bk {
			return ak < bk
		}
		return numLess(a, b)
	}
	if ak != reflect.String || bk != reflect.String {
		return ak < bk
	}
	ar, br := []rune(a.String()), []rune(b.String())
	for i := 0; i < len(ar) && i < len(br); i++ {
		if ar[i] == br[i] {
			continue
		}
		al := unicode.IsLetter(ar[i])
		bl := unicode.IsLetter(br[i])
		if al && bl {
			return ar[i] < br[i]
		}
		if al || bl {
			return bl
		}
		var ai, bi int
		var an, bn int64
		for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ {
			an = an*10 + int64(ar[ai]-'0')
		}
		for bi = i; bi < len(br) && unicode.IsDigit(br[bi]); bi++ {
			bn = bn*10 + int64(br[bi]-'0')
		}
		if an != bn {
			return an < bn
		}
		if ai != bi {
			return ai < bi
		}
		return ar[i] < br[i]
	}
	return len(ar) < len(br)
}
Exemple #22
0
// isIdent returns if a given input is a valid identifier
func isIdent(s string) bool {
	for i, r := range s {
		if i == 0 && !unicode.IsLetter(r) && r != '_' {
			return false
		} else if !unicode.IsLetter(r) && r != '_' && !unicode.IsDigit(r) {
			return false
		}
	}
	return true
}
Exemple #23
0
// compareLexicographic compares in "Debian lexicographic" way, see below compareVersionPart for details
func compareLexicographic(s1, s2 string) int {
	i := 0
	l1, l2 := len(s1), len(s2)

	for {
		if i == l1 && i == l2 {
			// s1 equal to s2
			break
		}

		if i == l2 {
			// s1 is longer than s2
			if s1[i] == '~' {
				return -1 // s1 < s2
			}
			return 1 // s1 > s2
		}

		if i == l1 {
			// s2 is longer than s1
			if s2[i] == '~' {
				return 1 // s1 > s2
			}
			return -1 // s1 < s2
		}

		if s1[i] == s2[i] {
			i++
			continue
		}

		if s1[i] == '~' {
			return -1
		}

		if s2[i] == '~' {
			return 1
		}

		c1, c2 := unicode.IsLetter(rune(s1[i])), unicode.IsLetter(rune(s2[i]))
		if c1 && !c2 {
			return -1
		}
		if !c1 && c2 {
			return 1
		}

		if s1[i] < s2[i] {
			return -1
		}
		return 1
	}
	return 0
}
Exemple #24
0
func rot13(s string) string {
	return strings.Map(func(c rune) rune {
		switch {
		case unicode.IsLetter(c + ROT):
			return c + ROT
		case unicode.IsLetter(c - ROT):
			return c - ROT
		}
		return c
	}, s)
}
func GetLastWord(linesrc string, off int) ([]string, []string) {

	wordsLeft := strings.FieldsFunc(linesrc[:off], func(r rune) bool {
		return !(unicode.IsLetter(r) || unicode.IsDigit(r))
	})

	wordsRight := strings.FieldsFunc(linesrc[off:], func(r rune) bool {
		return !(unicode.IsLetter(r) || unicode.IsDigit(r))
	})

	return wordsLeft, wordsRight
}
Exemple #26
0
func IsLegalIdentifier(s string) bool {
	us := utf8.NewString(s)
	if !unicode.IsLetter(us.At(0)) {
		return false
	}
	for i, c := range s {
		if !unicode.IsLetter(c) && (i == 0 || !unicode.IsDigit(c)) {
			return false
		}
	}
	return true
}
Exemple #27
0
func get_identifier(s string, sk *Stack) (rs string, ri int) {
	i := 0
	if s == "" {
		ri = 1
		return
	}
	iLen := len(s)
	// fmt.Printf("@@@%s@@@\n", s)

	con := true

	for i < iLen && con {
		switch {
		case unicode.IsLetter(rune(s[i])), unicode.IsNumber(rune(s[i])), s[i] == '_':
			i++
			for i < iLen {
				if unicode.IsLetter(rune(s[i])) || unicode.IsNumber(rune(s[i])) || s[i] == '_' {
					i++
				} else {
					break
				}
			}
			con = false
		case s[i] == ' ', s[i] == '\t':
			i++
		default:
			con = false
			i++
		}
	}
	// time.Sleep(time.Second)
	ts := s[:i]
	s1 := strings.Trim(ts, " ")
	s = s[i:]
	sk.Push(s1)
	rs = s
	switch s1 {
	case "":
		ri = -1
	case "char", "short", "int", "long", "float", "double", "auto", "signed", "unsigned", "const", "volatile", "static", "enum", "struct", "union", "void":
		ri = -1
	default:
		if !unicode.IsLetter(rune(s1[0])) && s1[0] != '_' {
			ri = -1
		} else {
			ri = 0
		}
	}
	return
	// fmt.Printf("<<<%d|%s|%s|%d>>>\n", iLen, ts[:i], ts[i:], i)

}
Exemple #28
0
func InsideAction(l *lex.Lexer) lex.StateFn {

	if l.Name == "LexTextNode" && strings.HasPrefix(l.Input[l.Pos:], rightDelim) {
		if l.IntState[ActionParenDepth] > 0 {
			return l.Errorf("unmatched parentheses")
		}
		return RightDelim
	}

	switch r := l.Next(); {
	case (r == lex.EOF || lex.IsEndOfLine(r)):
		if l.Name == "LexIfExpr" {
			return LexIfExpr
		}
		if l.Name == "LexForExpr" {
			return LexForExpr
		}
		// if reach eof throw while still in action throw error
		return l.Errorf("unclosed action")
	case lex.IsSpace(r):
		return Space
	case unicode.IsLetter(r): //variable and function must begin with a letter
		return Identifier
	case r == '!':
		if unicode.IsLetter(l.Peek()) {
			return Identifier
		}
		return l.Errorf("invalid character in builtin")
	case r == '#' || r == '+':
		if unicode.IsLetter(l.Peek()) {
			return EspraURI
		}
		return l.Errorf("invalid character in URI")
	case r == '-' || unicode.IsDigit(r):
		l.Backup()
		return Number
	case r == '\'' || r == '"':
		l.Emit(ItemOpenQuote)
		return String
	case r == '(':
		l.IntState[ActionParenDepth] += 1
		l.Emit(ItemLeftParen)
	case r == ')':
		l.IntState[ActionParenDepth] -= 1
		l.Emit(ItemRightParen)
	case r == '|':
		l.Emit(ItemPipe)
	default:
		return l.Errorf("Unexpected Character '%s'", string(r))
	}
	return InsideAction
}
Exemple #29
0
func (lex *lexer) Lex(lval *yySymType) int {
	lex.read = nil
	c := ' '

	for c == ' ' || c == '\t' {
		if len(lex.source) == 0 {
			return 0
		}
		c = lex.source[0]
		lex.read = append(lex.read, c)
		lex.source = lex.source[1:]
	}

	if c == '\n' {
		lex.line++
		return lex.Lex(lval)
	}

	if c == '(' || c == ')' || c == '+' || c == '-' || c == '*' || c == '/' || c == ';' || c == '{' || c == '}' {
		return int(c)
	}

	if c >= '0' && c <= '9' {
		lval.num = float64(c - '0')

		for lex.source[0] >= '0' && lex.source[0] <= '9' {
			lval.num *= 10
			lval.num += float64(lex.source[0] - '0')
			lex.read = append(lex.read, lex.source[0])
			lex.source = lex.source[1:]
		}

		return number
	}

	if unicode.IsLetter(c) || c == '_' {
		var i int
		for i = 0; i < len(lex.source); i++ {
			if !unicode.IsLetter(lex.source[i]) &&
				!unicode.IsDigit(lex.source[i]) &&
				lex.source[i] != '_' {
				break
			}
		}
		lval.ident = string(append([]rune{c}, lex.source[:i]...))
		lex.read = append(lex.read, lex.source[:i]...)
		lex.source = lex.source[i:]
		return identifier
	}

	return yyErrCode
}
Exemple #30
0
// lexSqlIndentifier scans input for valid sql identifier emiting the token on success
// and returning passed state function.
func (this *lexer) lexSqlIdentifier(typ tokenType, fn stateFn) stateFn {
	this.skipWhiteSpaces()
	// first rune has to be valid unicode letter
	if !unicode.IsLetter(this.next()) {
		return this.errorToken("identifier must begin with a letter " + this.current())
	}
	for rune := this.next(); unicode.IsLetter(rune) || unicode.IsDigit(rune); rune = this.next() {

	}
	this.backup()
	this.emit(typ)
	return fn
}