Ejemplo n.º 1
0
Archivo: lexer.go Proyecto: jmank88/gql
// The Lex method lexs the next token into t, or returns an error.
// Implements the Lexer interface.
func (l *lexer) Lex(t *token.Token) error {
	// Skip past whitespace, comments, etc.
	if !l.advanceToNextToken() {
		return l.err
	}

	t.Start = l.lastIndex

	if l.eof {
		t.Kind = token.EOF
		t.End = t.Start
		return nil
	}

	r := l.scanner.Rune()

	if k, exists := token.RunePunctuators[r]; exists {
		t.Kind = k
		t.End = t.Start + 1
		t.Value = string(r)
		if !l.advance() {
			return l.err
		}
		return nil
	}

	switch {
	case r == '_', l.isUpperLetter(), l.isLowerLetter():
		return l.readName(t)
	case r == '-', l.isDigit():
		return l.readNumber(t)
	case r < token.SPACE && r != token.TAB && r != token.LF && r != token.CR:
		return &SyntaxError{t.Start, fmt.Errorf("invalid character: %U", r)}
	}

	switch r {
	case '"':
		return l.readString(t)
	case '.':
		return l.readSpread(t)
	default:
		return &SyntaxError{t.Start, fmt.Errorf("unexpected character: %U", r)}
	}
}