// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package parse implements the VDL parser, converting source files into a parse
// tree.  The ParseFile function is the main entry point.
package parse

//go:generate ./grammar_gen.sh

// This is the only file in this package that uses the yacc-generated parser
// with entrypoint yyParse.  The result of the parse is the simple parse.File
// representation, which is used by the compilation stage.
//
// TODO(toddw): The yacc-generated parser returns pretty lousy error messages;
// basically "syntax error" is the only string returned.  Improve them.
import (
	"fmt"
	"io"
	"log"
	"math/big"
	"path"
	"strconv"
	"strings"
	"text/scanner"

	"v.io/x/ref/lib/vdl/vdlutil"
)

// Opts specifies vdl parsing options.
type Opts struct {
	ImportsOnly bool // Only parse imports; skip everything else.
}

// ParseFile takes a file name, the contents of the vdl file src, and the
// accumulated errors, and parses the vdl into a parse.File containing the parse
// tree.  Returns nil if any errors are encountered, with errs containing more
// information.  Otherwise returns the parsed File.
func ParseFile(fileName string, src io.Reader, opts Opts, errs *vdlutil.Errors) *File {
	start := startFile
	if opts.ImportsOnly {
		start = startFileImports
	}
	return parse(fileName, src, start, errs)
}

// ParseConfig takes a file name, the contents of the config file src, and the
// accumulated errors, and parses the config into a parse.Config containing the
// parse tree.  Returns nil if any errors are encountered, with errs containing
// more information.  Otherwise returns the parsed Config.
func ParseConfig(fileName string, src io.Reader, opts Opts, errs *vdlutil.Errors) *Config {
	start := startConfig
	if opts.ImportsOnly {
		start = startConfigImports
	}
	// Since the syntax is so similar between config files and vdl files, we just
	// parse it as a vdl file and populate Config afterwards.
	file := parse(fileName, src, start, errs)
	if file == nil {
		return nil
	}
	if len(file.ErrorDefs) > 0 || len(file.TypeDefs) > 0 || len(file.Interfaces) > 0 {
		errs.Errorf("%s: config files may not contain error, type or interface definitions", fileName)
		return nil
	}
	config := &Config{
		FileName:  fileName,
		Doc:       file.Doc,
		ConfigDef: file.PackageDef,
		Imports:   file.Imports,
		Config:    file.ConstDefs[0].Expr,
		ConstDefs: file.ConstDefs[1:],
	}
	if len(config.ConstDefs) == 0 {
		config.ConstDefs = nil
	}
	if opts.ImportsOnly {
		// Clear out the const expression from the config clause.
		config.Config = nil
		config.ConstDefs = nil
	}
	return config
}

func parse(fileName string, src io.Reader, startTok int, errs *vdlutil.Errors) *File {
	if errs == nil {
		log.Fatal("Nil errors specified for Parse")
	}
	origErrs := errs.NumErrors()
	lex := newLexer(fileName, src, startTok, errs)
	if errCode := yyParse(lex); errCode != 0 {
		errs.Errorf("%s: yyParse returned error code %v", fileName, errCode)
	}
	lex.attachComments()
	if startTok == startFile || startTok == startConfig {
		vdlutil.Vlog.Printf("PARSE RESULTS\n\n%v\n\n", lex.vdlFile)
	}
	if origErrs != errs.NumErrors() {
		return nil
	}
	return lex.vdlFile
}

// ParseExprs parses data into a slice of parsed const expressions.  The input
// data is specified in VDL syntax, with commas separating multiple expressions.
// There must be at least one expression specified in data.  Errors are returned
// in errs.
func ParseExprs(data string, errs *vdlutil.Errors) []ConstExpr {
	const name = "exprs"
	lex := newLexer(name, strings.NewReader(data), startExprs, errs)
	if errCode := yyParse(lex); errCode != 0 {
		errs.Errorf("vdl: yyParse returned error code %d", errCode)
	}
	return lex.exprs
}

// ExtractExprPackagePaths returns any package paths that appear in named constants
// in expr. i.e. "a/b/c".Foo => "a/b/c".
func ExtractExprPackagePaths(expr ConstExpr) []string {
	var paths []string
	switch e := expr.(type) {
	case *ConstNamed:
		if path := packageFromName(e.Name); len(path) > 0 {
			paths = append(paths, path)
		}
	case *ConstCompositeLit:
		for _, kv := range e.KVList {
			paths = append(paths, ExtractExprPackagePaths(kv.Key)...)
			paths = append(paths, ExtractExprPackagePaths(kv.Value)...)
		}
		paths = append(paths, ExtractTypePackagePaths(e.Type)...)
	case *ConstIndexed:
		paths = append(paths, ExtractExprPackagePaths(e.Expr)...)
		paths = append(paths, ExtractExprPackagePaths(e.IndexExpr)...)
	case *ConstTypeConv:
		paths = append(paths, ExtractTypePackagePaths(e.Type)...)
		paths = append(paths, ExtractExprPackagePaths(e.Expr)...)
	case *ConstTypeObject:
		paths = append(paths, ExtractTypePackagePaths(e.Type)...)
	case *ConstBinaryOp:
		paths = append(paths, ExtractExprPackagePaths(e.Lexpr)...)
		paths = append(paths, ExtractExprPackagePaths(e.Rexpr)...)
	case *ConstUnaryOp:
		paths = append(paths, ExtractExprPackagePaths(e.Expr)...)
	default:
		// leaf expression with no embedded expressions or types.
	}
	return paths
}

func ExtractTypePackagePaths(typ Type) []string {
	var paths []string
	switch t := typ.(type) {
	case *TypeNamed:
		if path := packageFromName(t.Name); len(path) > 0 {
			paths = append(paths, path)
		}
	case *TypeArray:
		paths = append(paths, ExtractTypePackagePaths(t.Elem)...)
	case *TypeList:
		paths = append(paths, ExtractTypePackagePaths(t.Elem)...)
	case *TypeSet:
		paths = append(paths, ExtractTypePackagePaths(t.Key)...)
	case *TypeMap:
		paths = append(paths, ExtractTypePackagePaths(t.Key)...)
		paths = append(paths, ExtractTypePackagePaths(t.Elem)...)
	case *TypeStruct:
		for _, f := range t.Fields {
			paths = append(paths, ExtractTypePackagePaths(f.Type)...)
		}
	case *TypeUnion:
		for _, f := range t.Fields {
			paths = append(paths, ExtractTypePackagePaths(f.Type)...)
		}
	case *TypeOptional:
		paths = append(paths, ExtractTypePackagePaths(t.Base)...)
	default:
		// leaf type with no embedded types.
	}
	return paths
}

func packageFromName(name string) string {
	if strings.HasPrefix(name, `"`) {
		if parts := strings.SplitN(name[1:], `".`, 2); len(parts) == 2 {
			return parts[0]
		}
	}
	return ""
}

// lexer implements the yyLexer interface for the yacc-generated parser.
//
// An oddity: lexer also holds the result of the parse.  Most yacc examples hold
// parse results in package-scoped (global) variables, but doing that would mean
// we wouldn't be able to run separate parses concurrently.  To enable that we'd
// need each invocation of yyParse to mutate its own result, but unfortunately
// the Go yacc tool doesn't provide any way to pass extra arguments to yyParse.
//
// So we cheat and hold the parse result in the lexer, and in the yacc rules we
// call lexVDLFile(yylex) to convert from the yyLexer interface back to the
// concrete lexer type, and retrieve a pointer to the parse result.
type lexer struct {
	// Fields for lexing / scanning the input source file.
	name     string
	scanner  scanner.Scanner
	errs     *vdlutil.Errors
	startTok int   // One of our dummy start tokens.
	started  bool  // Has the dummy start token already been emitted?
	sawEOF   bool  // Have we already seen the end-of-file?
	prevTok  token // Previous token, used for auto-semicolons and errors.

	// Fields holding the result of file and config parsing.
	comments commentMap
	vdlFile  *File

	// Field holding the result of expr parsing.
	exprs []ConstExpr
}

func newLexer(fileName string, src io.Reader, startTok int, errs *vdlutil.Errors) *lexer {
	l := &lexer{name: fileName, errs: errs, startTok: startTok, vdlFile: &File{BaseName: path.Base(fileName)}}
	l.comments.init()
	l.scanner.Init(src)
	// Don't produce character literal tokens, but do scan comments.
	l.scanner.Mode = scanner.ScanIdents | scanner.ScanFloats | scanner.ScanStrings | scanner.ScanRawStrings | scanner.ScanComments
	// Don't treat '\n' as whitespace, so we can auto-insert semicolons.
	l.scanner.Whitespace = 1<<'\t' | 1<<'\r' | 1<<' '
	l.scanner.Error = func(s *scanner.Scanner, msg string) {
		l.Error(msg)
	}
	return l
}

type token struct {
	t    rune
	text string
	pos  Pos
}

func (t token) String() string {
	return fmt.Sprintf("%v %U %s", t.pos, t.t, t.text)
}

// The lex* functions below all convert the yyLexer input arg into a concrete
// lexer as their first step.  The type conversion is always safe since we're
// the ones who called yyParse, and thus know the concrete type is always lexer.

// lexVDLFile retrieves the File parse result from the yyLexer interface.  This
// is called in the yacc rules to fill in the parse result.
func lexVDLFile(yylex yyLexer) *File {
	return yylex.(*lexer).vdlFile
}

// lexPosErrorf adds an error with positional information, on a type
// implementing the yyLexer interface.  This is called in the yacc rules to
// throw errors.
func lexPosErrorf(yylex yyLexer, pos Pos, format string, v ...interface{}) {
	yylex.(*lexer).posErrorf(pos, format, v...)
}

// lexGenEOF tells the lexer to generate EOF tokens from now on, as if the end
// of file had been seen.  This is called in the yacc rules to terminate the
// parse even if the file still has tokens.
func lexGenEOF(yylex yyLexer) {
	yylex.(*lexer).sawEOF = true
}

// lexStoreExprs stores the parsed exprs in the lexer.
func lexStoreExprs(yylex yyLexer, exprs []ConstExpr) {
	yylex.(*lexer).exprs = exprs
}

var keywords = map[string]int{
	"const":      tCONST,
	"enum":       tENUM,
	"error":      tERROR,
	"import":     tIMPORT,
	"interface":  tINTERFACE,
	"map":        tMAP,
	"package":    tPACKAGE,
	"set":        tSET,
	"stream":     tSTREAM,
	"struct":     tSTRUCT,
	"type":       tTYPE,
	"typeobject": tTYPEOBJECT,
	"union":      tUNION,
}

type nextRune struct {
	t  rune
	id int
}

// knownPunct is a map of our known punctuation.  We support 1 and 2 rune
// combinations, where 2 rune combos must be immediately adjacent with no
// intervening whitespace.  The 2-rune combos always take precedence over the
// 1-rune combos.  Every entry is a valid 1-rune combo, which is returned as-is
// without a special token id; the ascii value represents itself.
var knownPunct = map[rune][]nextRune{
	';': nil,
	':': nil,
	',': nil,
	'.': nil,
	'*': nil,
	'(': nil,
	')': nil,
	'[': nil,
	']': nil,
	'{': nil,
	'}': nil,
	'+': nil,
	'-': nil,
	'/': nil,
	'%': nil,
	'^': nil,
	'?': nil,
	'!': {{'=', tNE}},
	'=': {{'=', tEQEQ}},
	'<': {{'=', tLE}, {'<', tLSH}},
	'>': {{'=', tGE}, {'>', tRSH}},
	'|': {{'|', tOROR}},
	'&': {{'&', tANDAND}},
}

// autoSemi determines whether to automatically add a semicolon, based on the
// rule that semicolons are always added at the end of each line after certain
// tokens.  The Go auto-semicolon rule is described here:
//   http://golang.org/ref/spec#Semicolons
func autoSemi(prevTok token) bool {
	return prevAutoSemi[prevTok.t] && prevTok.pos.IsValid()
}

var prevAutoSemi = map[rune]bool{
	scanner.Ident:     true,
	scanner.Int:       true,
	scanner.Float:     true,
	scanner.String:    true,
	scanner.RawString: true,
	')':               true,
	']':               true,
	'}':               true,
	'>':               true,
}

const yaccEOF int = 0 // yacc interprets 0 as the end-of-file marker

func init() {
	// yyDebug is defined in the yacc-generated grammar.go file.  Setting it to 1
	// only produces output on syntax errors; set it to 4 to generate full debug
	// output.  Sadly yacc doesn't give position information describing the error.
	yyDebug = 1
}

// A note on the comment-tracking strategy.  During lexing we generate
// commentBlocks, defined as a sequence of adjacent or abutting comments (either
// // or /**/) with no intervening tokens.  Adjacent means that the previous
// comment ends on the line immediately before the next one starts, and abutting
// means that the previous comment ends on the same line as the next one starts.
//
// At the end of the parse we try to attach comment blocks to parse tree items.
// We use a heuristic that works for common cases, but isn't perfect - it
// mis-associates some styles of comments, and we don't ensure all comment
// blocks will be associated to an item.

type commentBlock struct {
	text      string
	firstLine int
	lastLine  int
}

// update returns true and adds tok to this block if tok is adjacent or
// abutting, otherwise it returns false without mutating the block.  Since we're
// handling newlines explicitly in the lexer, we never get comment tokens with
// trailing newlines.  We can get embedded newlines via /**/ style comments.
func (cb *commentBlock) update(tok token) bool {
	if cb.text == "" {
		// First update in this block.
		cb.text = tok.text
		cb.firstLine = tok.pos.Line
		cb.lastLine = tok.pos.Line + strings.Count(tok.text, "\n")
		return true
	}
	if cb.lastLine >= tok.pos.Line-1 {
		// The tok is adjacent or abutting.
		if cb.lastLine == tok.pos.Line-1 {
			// The tok is adjacent - need a newline.
			cb.text += "\n"
			cb.lastLine++
		}
		cb.text += tok.text
		cb.lastLine += strings.Count(tok.text, "\n")
		return true
	}
	return false
}

// commentMap keeps track of blocks of comments in a file.  We store comment
// blocks in maps by first line, and by last line.  Note that technically there
// could be more than one commentBlock ending on the same line, due to /**/
// style comments.  We ignore this rare case and just keep the first one.
type commentMap struct {
	byFirst      map[int]commentBlock
	byLast       map[int]commentBlock
	cur          commentBlock
	prevTokenPos Pos
}

func (cm *commentMap) init() {
	cm.byFirst = make(map[int]commentBlock)
	cm.byLast = make(map[int]commentBlock)
}

// addComment adds a comment token to the map, either appending to the current
// block or ending the current block and starting a new one.
func (cm *commentMap) addComment(tok token) {
	if !cm.cur.update(tok) {
		cm.endBlock()
		if !cm.cur.update(tok) {
			panic(fmt.Errorf("vdl: couldn't update current comment block with token %v", tok))
		}
	}
	// Here's an example of why we need the special case endBlock logic.
	//
	//   type Foo struct {
	//     // doc1
	//     A int // doc2
	//     // doc3
	//     B int
	//   }
	//
	// The problem is that without the special-case, we'd group doc2 and doc3
	// together into the same block.  That may actually be correct some times, but
	// it's more common for doc3 to be semantically associated with field B.  Thus
	// if we've already seen any token on the same line as this comment block, we
	// end the block immediately.  This means that comments appearing on the same
	// line as any other token are forced to be a single comment block.
	if cm.prevTokenPos.Line == tok.pos.Line {
		cm.endBlock()
	}
}

func (cm *commentMap) handleToken(tok token) {
	cm.endBlock()
	cm.prevTokenPos = tok.pos
}

// endBlock adds the the current comment block to the map, and resets it in
// preparation for new comments to be added.  In the rare case where we see
// comment blocks that either start or end on the same line, we just keep the
// first comment block that was inserted.
func (cm *commentMap) endBlock() {
	_, inFirst := cm.byFirst[cm.cur.firstLine]
	_, inLast := cm.byLast[cm.cur.lastLine]
	if cm.cur.text != "" && !inFirst && !inLast {
		cm.byFirst[cm.cur.firstLine] = cm.cur
		cm.byLast[cm.cur.lastLine] = cm.cur
	}
	cm.cur.text = ""
	cm.cur.firstLine = 0
	cm.cur.lastLine = 0
}

// getDoc returns the documentation string associated with pos.  Our rule is the
// last line of the documentation must end on the line immediately before pos.
// Once a comment block has been returned it isn't eligible to be attached to
// any other item, and is deleted from the map.
//
// The returned string is either empty, or is newline terminated.
func (cm *commentMap) getDoc(pos Pos) string {
	block := cm.byLast[pos.Line-1]
	if block.text == "" {
		return ""
	}
	doc := block.text + "\n"
	delete(cm.byFirst, block.firstLine)
	delete(cm.byLast, block.lastLine)
	return doc
}

// getDocSuffix returns the suffix documentation associated with pos.  Our rule
// is the first line of the documentation must be on the same line as pos.  Once
// a comment block has been returned it isn't eligible to be attached to any
// other item, and is deleted from the map.
//
// The returned string is either empty, or has a leading space.
func (cm *commentMap) getDocSuffix(pos Pos) string {
	block := cm.byFirst[pos.Line]
	if block.text == "" {
		return ""
	}
	doc := " " + block.text
	delete(cm.byFirst, block.firstLine)
	delete(cm.byLast, block.lastLine)
	return doc
}

// getFileDoc returns the file documentation.  Our rule is that the first line
// of the documentation must occur on the first line of the file, and all other
// comments must have already been attached.  Once a comment block has been
// returned it isn't eligible to be attached to any other item, and is deleted
// from the map.
//
// The returned string is either empty, or is newline terminated.
func (cm *commentMap) getFileDoc() string {
	block := cm.byFirst[1]
	if block.text == "" {
		return ""
	}
	doc := block.text + "\n"
	delete(cm.byFirst, block.firstLine)
	delete(cm.byLast, block.lastLine)
	return doc
}

func attachTypeComments(t Type, cm *commentMap, suffix bool) {
	switch tu := t.(type) {
	case *TypeEnum:
		for _, label := range tu.Labels {
			if suffix {
				label.DocSuffix = cm.getDocSuffix(label.Pos)
			} else {
				label.Doc = cm.getDoc(label.Pos)
			}
		}
	case *TypeArray:
		attachTypeComments(tu.Elem, cm, suffix)
	case *TypeList:
		attachTypeComments(tu.Elem, cm, suffix)
	case *TypeSet:
		attachTypeComments(tu.Key, cm, suffix)
	case *TypeMap:
		attachTypeComments(tu.Key, cm, suffix)
		attachTypeComments(tu.Elem, cm, suffix)
	case *TypeStruct:
		for _, field := range tu.Fields {
			if suffix {
				field.DocSuffix = cm.getDocSuffix(field.Pos)
			} else {
				field.Doc = cm.getDoc(field.Pos)
			}
			attachTypeComments(field.Type, cm, suffix)
		}
	case *TypeUnion:
		for _, field := range tu.Fields {
			if suffix {
				field.DocSuffix = cm.getDocSuffix(field.Pos)
			} else {
				field.Doc = cm.getDoc(field.Pos)
			}
			attachTypeComments(field.Type, cm, suffix)
		}
	case *TypeOptional:
		attachTypeComments(tu.Base, cm, suffix)
	case *TypeNamed:
		// Terminate the recursion at named types.
	default:
		panic(fmt.Errorf("vdl: unhandled type %#v", t))
	}
}

// attachComments causes all comments collected during the parse to be attached
// to the appropriate parse tree items.  This should only be called after the
// parse has completed.
func (l *lexer) attachComments() {
	f := l.vdlFile
	// First attach all suffix docs - these occur on the same line.
	f.PackageDef.DocSuffix = l.comments.getDocSuffix(f.PackageDef.Pos)
	for _, x := range f.Imports {
		x.DocSuffix = l.comments.getDocSuffix(x.Pos)
	}
	for _, x := range f.ErrorDefs {
		x.DocSuffix = l.comments.getDocSuffix(x.Pos)
	}
	for _, x := range f.TypeDefs {
		x.DocSuffix = l.comments.getDocSuffix(x.Pos)
		attachTypeComments(x.Type, &l.comments, true)
	}
	for _, x := range f.ConstDefs {
		x.DocSuffix = l.comments.getDocSuffix(x.Pos)
	}
	for _, x := range f.Interfaces {
		x.DocSuffix = l.comments.getDocSuffix(x.Pos)
		for _, y := range x.Embeds {
			y.DocSuffix = l.comments.getDocSuffix(y.Pos)
		}
		for _, y := range x.Methods {
			y.DocSuffix = l.comments.getDocSuffix(y.Pos)
		}
	}
	// Now attach the docs - these occur on the line immediately before.
	f.PackageDef.Doc = l.comments.getDoc(f.PackageDef.Pos)
	for _, x := range f.Imports {
		x.Doc = l.comments.getDoc(x.Pos)
	}
	for _, x := range f.ErrorDefs {
		x.Doc = l.comments.getDoc(x.Pos)
	}
	for _, x := range f.TypeDefs {
		x.Doc = l.comments.getDoc(x.Pos)
		attachTypeComments(x.Type, &l.comments, false)
	}
	for _, x := range f.ConstDefs {
		x.Doc = l.comments.getDoc(x.Pos)
	}
	for _, x := range f.Interfaces {
		x.Doc = l.comments.getDoc(x.Pos)
		for _, y := range x.Embeds {
			y.Doc = l.comments.getDoc(y.Pos)
		}
		for _, y := range x.Methods {
			y.Doc = l.comments.getDoc(y.Pos)
		}
	}
	// Finally attach the top-level file doc - this occurs on the first line.
	f.Doc = l.comments.getFileDoc()
}

// nextToken uses the text/scanner package to scan the input for the next token.
func (l *lexer) nextToken() (tok token) {
	tok.t = l.scanner.Scan()
	tok.text = l.scanner.TokenText()
	// Both Pos and scanner.Position start line and column numbering at 1.
	tok.pos = Pos{Line: l.scanner.Position.Line, Col: l.scanner.Position.Column}
	return
}

// translateToken takes the token we just scanned, and translates it into a
// token usable by yacc (lval and id).  The done return arg is true when a real
// yacc token was generated, or false if we need another next/translate pass.
func (l *lexer) translateToken(tok token, lval *yySymType) (id int, done bool) {
	switch tok.t {
	case scanner.EOF:
		l.sawEOF = true
		if autoSemi(l.prevTok) {
			return ';', true
		}
		return yaccEOF, true

	case '\n':
		if autoSemi(l.prevTok) {
			return ';', true
		}
		// Returning done=false ensures next/translate will be called again so that
		// this newline is skipped; id=yaccEOF is a dummy value that's ignored.
		return yaccEOF, false

	case scanner.String, scanner.RawString:
		var err error
		lval.strpos.Pos = tok.pos
		lval.strpos.String, err = strconv.Unquote(tok.text)
		if err != nil {
			l.posErrorf(tok.pos, "can't convert token [%v] to string literal", tok)
		}
		return tSTRLIT, true

	case scanner.Int:
		lval.intpos.pos = tok.pos
		lval.intpos.int = new(big.Int)
		if _, ok := lval.intpos.int.SetString(tok.text, 0); !ok {
			l.posErrorf(tok.pos, "can't convert token [%v] to integer literal", tok)
		}
		return tINTLIT, true

	case scanner.Float:
		lval.ratpos.pos = tok.pos
		lval.ratpos.rat = new(big.Rat)
		if _, ok := lval.ratpos.rat.SetString(tok.text); !ok {
			l.posErrorf(tok.pos, "can't convert token [%v] to float literal", tok)
		}
		return tRATLIT, true

	case scanner.Ident:
		// Either the identifier is a known keyword, or we pass it through as IDENT.
		if keytok, ok := keywords[tok.text]; ok {
			lval.pos = tok.pos
			return keytok, true
		}
		lval.strpos.Pos = tok.pos
		lval.strpos.String = tok.text
		return tIDENT, true

	case scanner.Comment:
		l.comments.addComment(tok)
		// Comments aren't considered tokens, just like the '\n' case.
		return yaccEOF, false

	default:
		// Either the rune is in our known punctuation whitelist, or we've hit a
		// syntax error.
		if nextRunes, ok := knownPunct[tok.t]; ok {
			// Peek at the next rune and compare against our list of next runes.  If
			// we find a match we return the id in next, otherwise just return the
			// original rune.  This means that 2-rune tokens always take precedence
			// over 1-rune tokens.  Either way the pos is set to the original rune.
			lval.pos = tok.pos
			peek := l.scanner.Peek()
			for _, next := range nextRunes {
				if peek == next.t {
					l.scanner.Next()
					return next.id, true
				}
			}
			return int(tok.t), true
		}
		l.posErrorf(tok.pos, "unexpected token [%v]", tok)
		l.sawEOF = true
		return yaccEOF, true
	}
}

// Lex is part of the yyLexer interface, called by the yacc-generated parser.
func (l *lexer) Lex(lval *yySymType) int {
	// Emit a dummy start token indicating what type of parse we're performing.
	if !l.started {
		l.started = true
		switch l.startTok {
		case startFileImports, startFile, startConfigImports, startConfig, startExprs:
			return l.startTok
		default:
			panic(fmt.Errorf("vdl: unhandled parse start token %d", l.startTok))
		}
	}
	// Always return EOF after we've scanned it.  This ensures we emit EOF on the
	// next Lex call after scanning EOF and adding an auto-semicolon.
	if l.sawEOF {
		return yaccEOF
	}
	// Run next/translate in a loop to handle newline-triggered auto-semicolons;
	// nextToken needs to generate newline tokens so that we can trigger the
	// auto-semicolon logic, but if the newline doesn't generate an auto-semicolon
	// we should skip the token and move on to the next one.
	for {
		tok := l.nextToken()
		if id, done := l.translateToken(tok, lval); done {
			l.prevTok = tok
			l.comments.handleToken(tok)
			return id
		}
	}
}

// Error is part of the yyLexer interface, called by the yacc-generated parser.
// Unfortunately yacc doesn't give good error information - we dump the position
// of the previous scanned token as an approximation of where the error is.
func (l *lexer) Error(s string) {
	l.posErrorf(l.prevTok.pos, "%s", s)
}

// posErrorf generates an error with file and pos info.
func (l *lexer) posErrorf(pos Pos, format string, v ...interface{}) {
	var posstr string
	if pos.IsValid() {
		posstr = pos.String()
	}
	l.errs.Errorf(l.name+":"+posstr+" "+format, v...)
}
