예제 #1
1
// 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
}
예제 #2
0
파일: string.go 프로젝트: shuLhan/tekstus
/*
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)
}
예제 #3
0
파일: persec.go 프로젝트: chlunde/persec
func delta(a, b string, elapsed time.Duration, w io.Writer) {
	var ai, bi int
	for {
		for ai < len(a) && !unicode.IsDigit(rune(a[ai])) {
			w.Write([]byte{a[ai]})
			ai++
		}

		for bi < len(b) && !unicode.IsDigit(rune(b[bi])) {
			bi++
		}

		if ai == len(a) {
			break
		}

		numA, lenA := collectDigits(a[ai:])
		ai += lenA

		numB, lenB := collectDigits(b[bi:])
		bi += lenB

		// TODO: look at the next words, what's the unit?
		// TODO: colors
		// TODO: KB/MB
		fmt.Fprintf(w, "%.2f/s",
			float64(numB-numA)/(float64(elapsed)/float64(time.Second*1)))
	}
	fmt.Fprintln(w)
}
예제 #4
0
파일: netpbm.go 프로젝트: tburke/netpbm
// GetNextInt returns the next base-10 integer read from a netpbmReader,
// skipping preceding whitespace and comments.
func (nr *netpbmReader) GetNextInt() int {
	// Find the first digit.
	var c rune
	for nr.err == nil && !unicode.IsDigit(c) {
		for c = nr.GetNextByteAsRune(); unicode.IsSpace(c); c = nr.GetNextByteAsRune() {
		}
		if c == '#' {
			// Comment -- discard the rest of the line.
			for c = nr.GetNextByteAsRune(); c != '\n'; c = nr.GetNextByteAsRune() {
			}
		}
	}
	if nr.err != nil {
		return -1
	}

	// Read while we have base-10 digits.  Return the resulting int.
	value := int(c - '0')
	for c = nr.GetNextByteAsRune(); unicode.IsDigit(c); c = nr.GetNextByteAsRune() {
		value = value*10 + int(c-'0')
	}
	if nr.err != nil {
		return -1
	}
	nr.err = nr.UnreadByte()
	if nr.err != nil {
		return -1
	}
	return value
}
예제 #5
0
// lexValueSequence scans a value sequence of a series description.
func lexValueSequence(l *lexer) stateFn {
	switch r := l.next(); {
	case r == eof:
		return lexStatements
	case isSpace(r):
		lexSpace(l)
	case r == '+':
		l.emit(itemADD)
	case r == '-':
		l.emit(itemSUB)
	case r == 'x':
		l.emit(itemTimes)
	case r == '_':
		l.emit(itemBlank)
	case unicode.IsDigit(r) || (r == '.' && unicode.IsDigit(l.peek())):
		l.backup()
		lexNumber(l)
	case isAlpha(r):
		l.backup()
		// We might lex invalid items here but this will be caught by the parser.
		return lexKeywordOrIdentifier
	default:
		return l.errorf("unexpected character in series sequence: %q", r)
	}
	return lexValueSequence
}
예제 #6
0
func ParseQuestion(s string) *Question {
	var isDigit bool
	positions := make([]int, 0)
	i, start := 0, -1

	for _, c := range s {
		isDigit = unicode.IsDigit(c)
		if start == -1 {
			if isDigit {
				start = i
			}
		} else if !isDigit {
			// Include a number's decimals, commas, and trailing commas (for percentages)
			if c != '%' && !((c == '.' || c == ',') && i < len(s)-1 && unicode.IsDigit(rune(s[i+1]))) {
				positions = append(positions, start, i-1)
				start = -1
			}
		}
		i++
	}

	if len(positions) > 0 {
		return &Question{
			FullText:  s,
			Positions: positions,
		}
	} else {
		return nil
	}
}
예제 #7
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
}
예제 #8
0
// 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
}
예제 #9
0
func scanFormat(l *State, fs string) string {
	i := 0
	skipDigit := func() {
		if unicode.IsDigit(rune(fs[i])) {
			i++
		}
	}
	flags := "-+ #0"
	for i < len(fs) && strings.ContainsRune(flags, rune(fs[i])) {
		i++
	}
	if i >= len(flags) {
		Errorf(l, "invalid format (repeated flags)")
	}
	skipDigit()
	skipDigit()
	if fs[i] == '.' {
		i++
		skipDigit()
		skipDigit()
	}
	if unicode.IsDigit(rune(fs[i])) {
		Errorf(l, "invalid format (width or precision too long)")
	}
	i++
	return "%" + fs[:i]
}
예제 #10
0
파일: lexer_selector.go 프로젝트: se77en/c6
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
}
예제 #11
0
파일: lex.go 프로젝트: wutaizeng/kapacitor
func lexNumberOrDurationOrDot(l *lexer) stateFn {
	foundDecimal := false
	first := true
	for {
		switch r := l.next(); {
		case r == '.':
			if first && !unicode.IsDigit(l.peek()) {
				l.emit(TokenDot)
				return lexToken
			}
			if foundDecimal {
				return l.errorf("multiple decimals in number")
			}
			foundDecimal = true
		case unicode.IsDigit(r):
			//absorb
		case !foundDecimal && isDurUnit(r):
			if r == 'm' && l.peek() == 's' {
				l.next()
			}
			l.emit(TokenDuration)
			return lexToken
		default:
			l.backup()
			l.emit(TokenNumber)
			return lexToken
		}
		first = false
	}
}
예제 #12
0
파일: lexer.go 프로젝트: kiljacken/jai
func (p *PrimaryLexer) scanNumeral() {
	buf := new(bytes.Buffer)

	first := p.Consume()
	buf.WriteRune(first)

	if first == '0' && p.Peek() == 'x' {
		// Hexadecimal
		buf.WriteRune(p.Consume())

		if !isHexadecimal(p.Peek()) {
			p.Emit(TokenError, "Expected digits after '0x' while lexing hexadecimal numeral")
			return
		}

		for isHexadecimal(p.Peek()) {
			buf.WriteRune(p.Consume())
		}
	} else {
		// Decimal
		for unicode.IsDigit(p.Peek()) {
			buf.WriteRune(p.Consume())
		}

		// Decimal digits
		if p.Peek() == '.' {
			dot := p.Consume()

			// Special case: 'digits' '..' 'expr'
			if !unicode.IsDigit(p.Peek()) {
				p.Emit(TokenNumeral, buf.String())
				p.Emit(TokenSymbol, ".")

				return
			}

			buf.WriteRune(dot)

			for unicode.IsDigit(p.Peek()) {
				buf.WriteRune(p.Consume())
			}
		}

		// Exponent
		if p.Peek() == 'e' {
			buf.WriteRune(p.Consume())

			if !unicode.IsDigit(p.Peek()) {
				p.Emit(TokenError, "Expected digits after '"+buf.String()+"' while lexing exponent of numeral")
				return
			}

			for unicode.IsDigit(p.Peek()) {
				buf.WriteRune(p.Consume())
			}
		}
	}

	p.Emit(TokenNumeral, buf.String())
}
예제 #13
0
파일: scanner.go 프로젝트: tboronczyk/Kiwi
// scanNumber consumes a numeric lexeme and returns its token and value. The
// numeric value may be an integer or real number.
func (s *Scanner) scanNumber() (token.Token, string) {
	var ch rune
	var buf bytes.Buffer

	buf.WriteRune(s.read())
	for {
		ch = s.read()
		if !unicode.IsDigit(ch) {
			break
		}
		buf.WriteRune(ch)
	}

	if ch == '.' {
		buf.WriteRune(ch)
		for {
			ch = s.read()
			if !unicode.IsDigit(ch) {
				break
			}
			buf.WriteRune(ch)
		}
	}
	s.unread()

	return token.NUMBER, buf.String()
}
예제 #14
0
//	statefull tokenizer for linux printk() message buffer
//
//	BUG(nath): may need some generic API
func get_klog_tokenizer() func(rune) bool {
	started := false
	state := "priority"

	return func(c rune) bool {
		switch state {

		case "dispatch":
			switch {
			case c == '<':
				state = "priority"
				started = true
				return true

			case c == '[':
				state = "date"
				started = true
				return true

			case started:
				state = "message"
				return unicode.IsSpace(c)

			default:
				started = true
				return true
			}

		case "priority":
			switch {
			case c == '<':
				return true

			case c == '>':
				state = "dispatch"
				return true

			default:
				return !unicode.IsDigit(c)
			}

		case "date":
			switch {
			case c == '[' || c == '.':
				return true

			case c == ']':
				state = "dispatch"
				return true

			default:
				return !unicode.IsDigit(c)
			}

		default:
			return false
		}
	}
}
예제 #15
0
파일: cursor.go 프로젝트: kybin/tor
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
}
예제 #16
0
파일: sorter.go 프로젝트: 9cc9/dea_ng
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)
}
예제 #17
0
파일: lex.go 프로젝트: jnschaeffer/scheme
func lexStart(l *lexer) stateFn {
	switch r := l.next(); {
	case isWhitespace(r):
		return lexWhitespace
	case r == '(':
		l.emit(LPAREN)
		return lexStart
	case r == ')':
		l.emit(RPAREN)
		return lexStart
	case r == '\'':
		l.emit(QUOTE)
		return lexStart
	case r == '`':
		l.emit(BACKTICK)
		return lexStart
	case r == ',':
		if l.peek() == '@' {
			l.next()
			l.emit(COMMAAT)
		} else {
			l.emit(COMMA)
		}
		return lexStart
	case r == '.' && !unicode.IsDigit(l.peek()):
		l.emit(DOT)
		return lexStart
	case (r == '+' || r == '-') && !unicode.IsDigit(l.peek()):
		l.emit(IDENT)
		return lexStart
	case r == '.' || r == '+' || r == '-' || ('0' <= r && r <= '9'):
		l.backup()
		return lexNumber
	case r == '"':
		l.ignore()
		return lexString
	case r == '#':
		switch r = l.next(); {
		case r == 't' || r == 'f':
			l.backup()
			return lexBoolean
		case r == '\\':
			return lexCharacter
		case r == '(':
			l.emit(LVEC)
			return lexStart
		default:
			return l.errorf("bad # sequence")
		}
	case r == eof || r == '\n':
		return nil
	default:
		l.backup()
		return lexIdentifier
	}

	return lexStart
}
예제 #18
0
파일: read.go 프로젝트: koji-m/yuyo
func readSymbolOrNumber(prt *port, head rune) (yObj, error) {
	var (
		c rune
		e error
	)

	if head != -1 {
		c, e = head, nil
	} else {
		c, _, e = prt.rdr.ReadRune()
	}
	if e != nil {
		return nil, mkYerror(errRead, errIntern)
	}

	switch c {
	case '.':
		next, _, e := prt.rdr.ReadRune()
		if e != nil {
			return nil, mkYerror(errRead, errIntern)
		}
		if next == '.' {
			e = prt.rdr.UnreadRune()
			if e != nil {
				return nil, mkYerror(errRead, errIntern)
			}
			return readSymbol(prt, '.')
		}
		if unicode.IsDigit(next) {
			e = prt.rdr.UnreadRune()
			if e != nil {
				return nil, mkYerror(errRead, errIntern)
			}
			return readNumber(prt, c)
		}
		return nil, mkYerror(errRead, errSyntax, "malformed dot syntax")
	case '+', '-':
		next, _, e := prt.rdr.ReadRune()
		if e != nil {
			return nil, mkYerror(errRead, errIntern)
		}
		if unicode.IsDigit(next) || (next >= 'a' && next <= 'f') || next == 'i' || next == '.' {
			e = prt.rdr.UnreadRune()
			if e != nil {
				return nil, mkYerror(errRead, errIntern)
			}
			return readNumber(prt, c)
		}
		e = prt.rdr.UnreadRune()
		if e != nil {
			return nil, mkYerror(errRead, errIntern)
		}
		return readSymbol(prt, c)
	default:
		return nil, mkYerror(errRead, errSyntax, "unrecognized syntax")
	}
}
예제 #19
0
파일: lex.go 프로젝트: dushmis/go
func (l *lexer) ident(c rune) {
	cp := &lexbuf
	cp.Reset()

	// accelerate common case (7bit ASCII)
	for isLetter(c) || isDigit(c) {
		cp.WriteByte(byte(c))
		c = l.getr()
	}

	// general case
	for {
		if c >= utf8.RuneSelf {
			if unicode.IsLetter(c) || c == '_' || unicode.IsDigit(c) {
				if cp.Len() == 0 && unicode.IsDigit(c) {
					yyerror("identifier cannot begin with digit %#U", c)
				}
			} else {
				yyerror("invalid identifier character %#U", c)
			}
			cp.WriteRune(c)
		} else if isLetter(c) || isDigit(c) {
			cp.WriteByte(byte(c))
		} else {
			break
		}
		c = l.getr()
	}

	cp = nil
	l.ungetr()

	name := lexbuf.Bytes()

	if len(name) >= 2 {
		if tok, ok := keywords[string(name)]; ok {
			if Debug['x'] != 0 {
				fmt.Printf("lex: %s\n", lexname(tok))
			}
			switch tok {
			case LBREAK, LCONTINUE, LFALL, LRETURN:
				l.nlsemi = true
			}
			l.tok = tok
			return
		}
	}

	s := lookupBytes(name)
	if Debug['x'] != 0 {
		fmt.Printf("lex: ident %v\n", s)
	}
	l.sym_ = s
	l.nlsemi = true
	l.tok = LNAME
}
예제 #20
0
파일: regexp.go 프로젝트: bak1an/sre2
// Consume a single rune; assumes this is being invoked as the last possible
// option and will panic if an invalid escape sequence is found. Will return the
// found rune (as an integer) and with cursor past the entire representation.
func (p *parser) single_rune() rune {
	if r := p.src.curr(); r != '\\' {
		// This is just a regular character; return it immediately.
		p.src.nextCh()
		return r
	}

	if p.src.peek() == 'x' {
		// Match hex character code.
		var hex string
		p.src.nextCh()
		if p.src.nextCh() == '{' {
			hex = p.src.literal("{", "}")
		} else {
			hex = fmt.Sprintf("%c%c", p.src.curr(), p.src.nextCh())
			p.src.nextCh() // Step over the end of the hex code.
		}

		// Parse and return the corresponding rune.
		raw, err := strconv.ParseUint(hex, 16, 32)
		if err != nil {
			panic(fmt.Sprintf("couldn't parse hex: %s", hex))
		}
		return rune(raw)
	} else if r := ESCAPES[p.src.peek()]; r != 0 {
		// Literally match '\n', '\r', etc.
		p.src.nextCh()
		p.src.nextCh()
		return r
	} else if unicode.Is(posix_groups["punct"], p.src.peek()) {
		// Allow punctuation to be blindly escaped.
		r := p.src.nextCh()
		p.src.nextCh()
		return r
	} else if unicode.IsDigit(p.src.peek()) {
		// Match octal character code (begins with digit, up to three digits).
		oct := ""
		p.src.nextCh()
		for i := 0; i < 3; i++ {
			oct += fmt.Sprintf("%c", p.src.curr())
			if !unicode.IsDigit(p.src.nextCh()) {
				break
			}
		}

		// Parse and return the corresponding rune.
		raw, err := strconv.ParseUint(oct, 8, 32)
		if err != nil {
			panic(fmt.Sprintf("couldn't parse oct: %s", oct))
		}
		return rune(raw)
	}

	// This is an escape sequence which does not identify a single rune.
	panic(fmt.Sprintf("not a valid escape sequence: \\%c", p.src.peek()))
}
예제 #21
0
파일: lexer.go 프로젝트: ctliu3/Gosp
func lexWhitespace(l *Lexer) StateFn {
	var r rune
	for r = l.next(); isSpace(r); r = l.next() {
	}
	l.backward()
	l.ignore()

	switch r = l.next(); {
	case r == '(':
		return lexLeftParen
	case r == ')':
		return lexRightParen
	case r == '[':
		return lexLeftVect
	case r == ']':
		return lexRightVect
	case r == '"':
		return lexString
	case r == '\'':
		return lexQuote
	case r == '`':
		return lexQuasiQuote
	case r == ',':
		if l.next() == '@' {
			return lexUnQuoteSplicing
		} else {
			l.backward()
			return lexUnQuote
		}
	case r == ';':
		return lexComment
	case r == '#':
		return lexSharp
	case r == '-' || r == '+' || unicode.IsDigit(r): // number or ident
		next := l.peek()
		if next == EOF {
			panic("expected number or procedure")
		}
		if !unicode.IsDigit(r) && isSpace(next) {
			return lexIdentifier
		}
		if scanNumber(l) {
			return lexNumber
		}

	case isAlphaNumeric(r):
		l.backward()
		return lexIdentifier
	case r == EOF:
		return lexEOF
	}

	return nil
}
예제 #22
0
파일: lex.go 프로젝트: ericchiang/pl
// lexNext lexes the item immediately following an identifier
func lexNext(l *lexer) stateFn {
	r := l.next()
	switch {
	case r == eof:
		return l.errorf("statement unterminated by '.'")
	case r == '.':
		if l.peek() == '(' {
			l.emit(itemAtom)
		} else {
			l.emit(itemDot)
			return lexSpace
		}
	case r == '|':
		l.emit(itemPipe)
	case r == '!':
		l.emit(itemCut)
	case r == ',':
		l.emit(itemComma)
	case r == '(':
		l.emit(itemLeftParen)
		l.parenDepth++
	case r == ')':
		l.emit(itemRightParen)
		l.parenDepth--
		if l.parenDepth < 0 {
			return l.errorf("unexpected right paren %#U", r)
		}
	case r == '[':
		l.emit(itemLeftBrace)
		l.braceDepth++
	case r == ']':
		l.emit(itemRightParen)
		l.parenDepth--
		if l.parenDepth < 0 {
			return l.errorf("unexpected right paren %#U", r)
		}
	case unicode.IsDigit(r):
		return lexNumber
	case unicode.IsUpper(r) || r == '_':
		return lexVariable
	case unicode.IsLower(r):
		return lexAtom
	case r == '\'' || r == '"':
		l.backup()
		return lexQuoted
	case unicode.IsDigit(r):
		l.backup()
		return lexNumber
	default:
		l.errorf("unexpected character %#U", r)
	}
	return lexNext
}
예제 #23
0
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
}
예제 #24
0
파일: lexer.go 프로젝트: defiant00/char
func lexNumber(l *Lexer) stateFn {
	for r := l.peek(); unicode.IsDigit(r); {
		l.next()
		r = l.peek()
	}
	l.accept(".")
	for r := l.peek(); unicode.IsDigit(r); {
		l.next()
		r = l.peek()
	}
	l.emit(token.NUMBER)
	return lexStatement
}
예제 #25
0
// Specialized function for TeX-style hyphenation patterns.  Accepts strings of the form '.hy2p'.
// The value it stores is of type vector.IntVector
func (p *Trie) AddPatternString(s string) {
	v := new(vector.IntVector)

	// precompute the Unicode rune for the character '0'
	rune0, _ := utf8.DecodeRune([]byte{'0'})

	strLen := len(s)

	// Using the range keyword will give us each Unicode rune.
	for pos, rune := range s {
		if unicode.IsDigit(rune) {
			if pos == 0 {
				// This is a prefix number
				v.Push(rune - rune0)
			}

			// this is a number referring to the previous character, and has
			// already been handled
			continue
		}

		if pos < strLen-1 {
			// look ahead to see if it's followed by a number
			next := int(s[pos+1])
			if unicode.IsDigit(next) {
				// next char is the hyphenation value for this char
				v.Push(next - rune0)
			} else {
				// hyphenation for this char is an implied zero
				v.Push(0)
			}
		} else {
			// last character gets an implied zero
			v.Push(0)
		}
	}

	pure := strings.Map(func(rune int) int {
		if unicode.IsDigit(rune) {
			return -1
		}
		return rune
	},
		s)
	leaf := p.addRunes(strings.NewReader(pure))
	if leaf == nil {
		return
	}

	leaf.value = v
}
예제 #26
0
func _dl_cache_libcmp(p1, p2 string) int {
	// log.Printf("Compare %q and %q", p1, p2)
	l := len(p1)
	if len(p2) < l {
		l = len(p2)
	}
	parseLeadingNum := func(s string) int {
		nonDigit := func(r rune) bool { return !unicode.IsDigit(r) }
		firstNonDigit := strings.IndexFunc(s, nonDigit)
		if firstNonDigit == -1 {
			// No numbers before end of string
			firstNonDigit = len(s)
		}
		n, err := strconv.ParseInt(s[:firstNonDigit], 10, 32)
		if err != nil {
			panic(err)
		}
		return int(n)
	}

	for i := 0; i < l; i++ {
		p1c, p2c := p1[i], p2[i]
		switch {
		case unicode.IsDigit(rune(p1c)) && unicode.IsDigit(rune(p2c)):
			// Must do a numerical compare.
			n1 := parseLeadingNum(p1[i:])
			n2 := parseLeadingNum(p2[i:])
			switch {
			case n1 < n2:
				return -1
			case n1 > n2:
				return 1
			}
		case unicode.IsDigit(rune(p1c)):
			return 1
		case unicode.IsDigit(rune(p2c)):
			return -1
		case p1c < p2c:
			return -1
		case p1c > p2c:
			return 1
		}
	}
	switch {
	case len(p1) < len(p2):
		return -1
	case len(p1) > len(p2):
		return 1
	}
	return 0
}
예제 #27
0
// These two steps (comparing and removing initial non-digit strings and initial digit strings) are
// repeated until a difference is found or both strings are exhausted."
func compareVersionPart(part1, part2 string) int {
	i1, i2 := 0, 0
	l1, l2 := len(part1), len(part2)

	for {
		j1, j2 := i1, i2
		for j1 < l1 && !unicode.IsDigit(rune(part1[j1])) {
			j1++
		}

		for j2 < l2 && !unicode.IsDigit(rune(part2[j2])) {
			j2++
		}

		s1, s2 := part1[i1:j1], part2[i2:j2]
		r := compareLexicographic(s1, s2)
		if r != 0 {
			return r
		}

		i1, i2 = j1, j2

		for j1 < l1 && unicode.IsDigit(rune(part1[j1])) {
			j1++
		}

		for j2 < l2 && unicode.IsDigit(rune(part2[j2])) {
			j2++
		}

		s1, s2 = part1[i1:j1], part2[i2:j2]
		n1, _ := strconv.Atoi(s1)
		n2, _ := strconv.Atoi(s2)

		if n1 < n2 {
			return -1
		}
		if n1 > n2 {
			return 1
		}

		i1, i2 = j1, j2

		if i1 == l1 && i2 == l2 {
			break
		}
	}
	return 0
}
예제 #28
0
func (self *tokenizer) Next() {
	self.token.Value = ""

	// Skip whitespace
	for unicode.IsSpace(self.char) {
		self.nextChar()
	}

	if self.char == '(' {
		self.token.Type = TOK_OPEN
		self.nextChar()

	} else if self.char == ')' {
		self.token.Type = TOK_CLOSE
		self.nextChar()

	} else if self.char == '.' {
		self.token.Type = TOK_DOT
		self.nextChar()

	} else if unicode.IsDigit(self.char) {
		self.token.Type = TOK_FIXNUM

		for {
			self.token.Value += string(self.char)
			self.nextChar()

			if !unicode.IsDigit(self.char) {
				break
			}
		}

	} else if isValidSymbolChar(self.char) {
		self.token.Type = TOK_SYMBOL

		for {
			self.token.Value += string(self.char)
			self.nextChar()

			if !isValidSymbolChar(self.char) {
				break
			}
		}

	} else {
		// End of input
		self.token.Type = TOK_EOF
	}
}
예제 #29
0
파일: lexer_states.go 프로젝트: c9s/guts
func lexNumber(l *GutsLex) stateFn {
	var c rune
	for c = l.next(); true; c = l.next() {
		if unicode.IsDigit(c) {
			continue
		} else if c == '.' && unicode.IsDigit(l.peek()) {
			return lexFloating
		} else {
			break
		}
	}
	l.backup()
	l.emit(T_NUMBER)
	return lexStart
}
예제 #30
0
func envValid(env string) bool {
	items := strings.Split(env, "=")
	if len(items) < 2 {
		return false
	}
	for i, ch := range strings.TrimSpace(items[0]) {
		if !unicode.IsDigit(ch) && !unicode.IsLetter(ch) && ch != '_' {
			return false
		}
		if i == 0 && unicode.IsDigit(ch) {
			logrus.Warnf("Env %v: variable name beginning with digit is not recommended.", env)
		}
	}
	return true
}