Skip to content
Snippets Groups Projects
parser.go 3.41 KiB
Newer Older
 * Copyright 2015 Manish R Jain <manishrjain@gmaicom>
 *
 * 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.
 */

package gql

import (
	"errors"
	"fmt"
	"strconv"

	"github.com/dgraph-io/dgraph/lex"
	"github.com/dgraph-io/dgraph/query"
	"github.com/dgraph-io/dgraph/x"
var glog = x.Log("gql")

func run(l *lex.Lexer) {
	for state := lexText; state != nil; {
		state = state(l)
	}
	close(l.Items) // No more tokens.
}

func Parse(input string) (sg *query.SubGraph, rerr error) {
	for item := range l.Items {
		if item.Typ == itemText {
		if item.Typ == itemOpType {
			if item.Val == "mutation" {
				return nil, errors.New("Mutations not supported")
			}
		}
			if sg == nil {
				sg, rerr = getRoot(l)
				if rerr != nil {
					x.Err(glog, rerr).Error("While retrieving subgraph root")
					return nil, rerr
				}
			} else {
				if err := godeep(l, sg); err != nil {
					return sg, err
				}
func getRoot(l *lex.Lexer) (sg *query.SubGraph, rerr error) {
	item := <-l.Items
	if item.Typ != itemName {
		return nil, fmt.Errorf("Expected some name. Got: %v", item)
	}
	// ignore itemName for now.
	item = <-l.Items
	if item.Typ != itemLeftRound {
		return nil, fmt.Errorf("Expected variable start. Got: %v", item)
	}

	var uid uint64
	var xid string
	for {
		var key, val string
		// Get key or close bracket
		item = <-l.Items
		if item.Typ == itemArgName {
			key = item.Val
		} else if item.Typ == itemRightRound {
			break
		} else {
			return nil, fmt.Errorf("Expecting argument name. Got: %v", item)
		}

		// Get corresponding value.
		item = <-l.Items
		if item.Typ == itemArgVal {
			val = item.Val
			return nil, fmt.Errorf("Expecting argument va Got: %v", item)
			uid, rerr = strconv.ParseUint(val, 0, 64)
			if rerr != nil {
				return nil, rerr
			}
			return nil, fmt.Errorf("Expecting _uid_ or _xid_. Got: %v", item)
		return nil, fmt.Errorf("Unexpected token. Got: %v", item)
	}
	return query.NewGraph(uid, xid)
}

func godeep(l *lex.Lexer, sg *query.SubGraph) error {
	curp := sg // Used to track current node, for nesting.
	for item := range l.Items {
		if item.Typ == lex.ItemError {
			return errors.New(item.Val)

		} else if item.Typ == lex.ItemEOF {
			return nil

		} else if item.Typ == itemName {
			sg.Children = append(sg.Children, child)
			curp = child

		} else if item.Typ == itemLeftCurl {
			if err := godeep(l, curp); err != nil {
				return err
			}

		} else if item.Typ == itemRightCurl {
			return nil

		} else if item.Typ == itemLeftRound {
			// absorb all these, we don't use them right now.
			for ti := range l.Items {
				if ti.Typ == itemRightRound || ti.Typ == lex.ItemEOF {
					return nil