Skip to content
Snippets Groups Projects
state.go 4.9 KiB
Newer Older
/*
 * Copyright 2015 Manish R Jain <manishrjain@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 		http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import "github.com/dgraph-io/dgraph/lex"

const (
	itemText       lex.ItemType = 5 + iota // plain text
	itemLeftCurl                           // left curly bracket
	itemRightCurl                          // right curly bracket
	itemComment                            // comment
	itemOpType                             // operation type
	itemString                             // quoted string
	itemLeftRound                          // left round bracket
	itemRightRound                         // right round bracket
	itemArgName                            // argument name
	itemArgVal                             // argument val
)
func lexText(l *lex.Lexer) lex.StateFn {
			l.Backup()
			l.Emit(itemText) // emit whatever we have so far.
			l.Next()         // advance one to get back to where we saw leftCurl.
			l.Depth += 1     // one level down.
			l.Emit(itemLeftCurl)
			return lexInside // we're in.

		case r == rightCurl:
			return l.Errorf("Too many right characters")
		case r == lex.EOF:
	if l.Pos > l.Start {
		l.Emit(itemText)
func lexInside(l *lex.Lexer) lex.StateFn {
			l.Depth -= 1
			l.Emit(itemRightCurl)
			if l.Depth == 0 {
			l.Depth += 1
			l.Emit(itemLeftCurl)
		case r == lex.EOF:
			return l.Errorf("unclosed action")
		case isSpace(r) || isEndOfLine(r) || r == ',':
		case isNameBegin(r):
			return lexName
		case r == '#':
Manish R Jain's avatar
Manish R Jain committed
		case r == '(':
Manish R Jain's avatar
Manish R Jain committed
			return lexArgInside
			return l.Errorf("Unrecognized character in lexInside: %#U", r)
func lexName(l *lex.Lexer) lex.StateFn {
Manish R Jain's avatar
Manish R Jain committed
		// The caller already checked isNameBegin, and absorbed one rune.
func lexComment(l *lex.Lexer) lex.StateFn {
	if l.Pos > l.Start {
		l.Emit(itemComment)
func lexOperationType(l *lex.Lexer) lex.StateFn {
		l.Backup()
		word := l.Input[l.Start:l.Pos]
		if word == "query" || word == "mutation" {
func lexArgInside(l *lex.Lexer) lex.StateFn {
Manish R Jain's avatar
Manish R Jain committed
	for {
		switch r := l.Next(); {
		case r == lex.EOF:
			return l.Errorf("unclosed argument")
Manish R Jain's avatar
Manish R Jain committed
		case isSpace(r) || isEndOfLine(r):
Manish R Jain's avatar
Manish R Jain committed
		case isNameBegin(r):
			return lexArgName
		case r == ':':
Manish R Jain's avatar
Manish R Jain committed
			return lexArgVal
		case r == ')':
Manish R Jain's avatar
Manish R Jain committed
			return lexInside
		case r == ',':
func lexArgName(l *lex.Lexer) lex.StateFn {
Manish R Jain's avatar
Manish R Jain committed
	for {
Manish R Jain's avatar
Manish R Jain committed
		if isNameSuffix(r) {
			continue
		}
Manish R Jain's avatar
Manish R Jain committed
		break
	}
	return lexArgInside
}

func lexArgVal(l *lex.Lexer) lex.StateFn {
	l.AcceptRun(isSpace)
	l.Ignore() // Any spaces encountered.
Manish R Jain's avatar
Manish R Jain committed
	for {
Manish R Jain's avatar
Manish R Jain committed
		if isSpace(r) || isEndOfLine(r) || r == ')' || r == ',' {
Manish R Jain's avatar
Manish R Jain committed
			return lexArgInside
		}
		if r == lex.EOF {
			return l.Errorf("Reached lex.EOF while reading var value: %v",
				l.Input[l.Start:l.Pos])
Manish R Jain's avatar
Manish R Jain committed
		}
	}
	glog.Fatal("This shouldn't be reached.")
	return nil
}

func lexArgumentVal(l *lex.Lexer) lex.StateFn {
Manish R Jain's avatar
Manish R Jain committed
	for {
Manish R Jain's avatar
Manish R Jain committed
		case isSpace(r):
func isSpace(r rune) bool {
	return r == '\u0009' || r == '\u0020'
}

func isEndOfLine(r rune) bool {
	return r == '\u000A' || r == '\u000D'
}

func isNameBegin(r rune) bool {
	switch {
	case r >= 'a' && r <= 'z':
		return true
	case r >= 'A' && r <= 'Z':
		return true
	case r == '_':
		return true
	default:
		return false
	}
func isNameSuffix(r rune) bool {
	if isNameBegin(r) {
		return true
	}
	if r >= '0' && r <= '9' {
		return true
	}
	if r == '.' || r == '-' { // Use by freebase.