// Code generated by goyacc -p cond cond.y. DO NOT EDIT.

//line cond.y:21

package parser

import __yyfmt__ "fmt"

//line cond.y:22

import (
	"fmt"
	"go/token"
)

//line cond.y:31
type condSymType struct {
	yys  int
	Node Node
	str  string
}

const IDENT = 57346
const LAND = 57347
const LOR = 57348
const LPAREN = 57349
const RPAREN = 57350
const NOT = 57351
const SEMICOLON = 57352
const BASICLIT = 57353
const COMMA = 57354
const BOOL = 57355
const STRING = 57356
const INT = 57357
const FLOAT = 57358
const IMAG = 57359
const COMMENT = 57360
const ILLEGAL = 57361

var condToknames = [...]string{
	"$end",
	"error",
	"$unk",
	"IDENT",
	"LAND",
	"LOR",
	"LPAREN",
	"RPAREN",
	"NOT",
	"SEMICOLON",
	"BASICLIT",
	"COMMA",
	"BOOL",
	"STRING",
	"INT",
	"FLOAT",
	"IMAG",
	"COMMENT",
	"ILLEGAL",
}

var condStatenames = [...]string{}

const condEofCode = 1
const condErrCode = 2
const condInitialStackSize = 16

//line cond.y:96

// The parser expects the lexer to return 0 on EOF.  Give it a name
// for clarity.
const EOF = 0

var (
	parseNode    Node // save parse node
	lastPos      token.Pos
	lastTokenPos token.Pos
)

// The parser uses the type <prefix>Lex as a lexer.  It must provide
// the methods Lex(*<prefix>SymType) int and Error(string).
type condLex struct {
	s   *Scanner
	err ErrorHandler
}

// The parser calls this method to get each new token.
func (x *condLex) Lex(yylval *condSymType) int {
	for {
		pos, tok, lit := x.s.Scan()

		lastPos = pos

		// fmt.Printf("got token %s %s\n", tok, lit)
		switch tok {
		case EOF:
			return EOF
		case IDENT:
			yylval.Node = &Ident{Name: lit, NamePos: pos}
			return IDENT
		case BOOL, STRING, INT:
			yylval.Node = &BasicLit{Kind: tok, Value: lit, ValuePos: pos}
			return BASICLIT
		case LPAREN, RPAREN, LAND, LOR, SEMICOLON, COMMA, NOT:
			lastTokenPos = pos
			return int(tok)
		default:
			x.Error(fmt.Sprintf("unrecognized token %d", tok))
			return EOF
		}
	}
}

// The parser calls this method on a parse error.
func (x *condLex) Error(s string) {
	if x.err != nil {
		x.err(lastPos, s)
	}
}

//line yacctab:1
var condExca = [...]int8{
	-1, 1,
	1, -1,
	-2, 0,
}

const condPrivate = 57344

const condLast = 23

var condAct = [...]int8{
	18, 20, 16, 2, 19, 17, 11, 9, 10, 8,
	6, 12, 13, 3, 15, 4, 7, 8, 5, 14,
	7, 8, 1,
}

var condPact = [...]int16{
	6, -1000, 15, 6, 6, -1000, -1, 6, 6, 11,
	-1000, -6, 3, -1000, -1000, -8, -1000, -1000, -1000, -10,
	-1000,
}

var condPgo = [...]int8{
	0, 22, 3, 18, 14,
}

var condR1 = [...]int8{
	0, 1, 2, 2, 2, 2, 2, 2, 3, 3,
	4, 4,
}

var condR2 = [...]int8{
	0, 1, 3, 3, 3, 2, 1, 1, 4, 3,
	1, 3,
}

var condChk = [...]int16{
	-1000, -1, -2, 7, 9, -3, 4, 5, 6, -2,
	-2, 7, -2, -2, 8, -4, 8, 11, 8, 12,
	11,
}

var condDef = [...]int8{
	0, -2, 1, 0, 0, 6, 7, 0, 0, 0,
	5, 0, 3, 4, 2, 0, 9, 10, 8, 0,
	11,
}

var condTok1 = [...]int8{
	1,
}

var condTok2 = [...]int8{
	2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
	12, 13, 14, 15, 16, 17, 18, 19,
}

var condTok3 = [...]int8{
	0,
}

var condErrorMessages = [...]struct {
	state int
	token int
	msg   string
}{}

//line yaccpar:1

/*	parser for yacc output	*/

var (
	condDebug        = 0
	condErrorVerbose = false
)

type condLexer interface {
	Lex(lval *condSymType) int
	Error(s string)
}

type condParser interface {
	Parse(condLexer) int
	Lookahead() int
}

type condParserImpl struct {
	lval  condSymType
	stack [condInitialStackSize]condSymType
	char  int
}

func (p *condParserImpl) Lookahead() int {
	return p.char
}

func condNewParser() condParser {
	return &condParserImpl{}
}

const condFlag = -1000

func condTokname(c int) string {
	if c >= 1 && c-1 < len(condToknames) {
		if condToknames[c-1] != "" {
			return condToknames[c-1]
		}
	}
	return __yyfmt__.Sprintf("tok-%v", c)
}

func condStatname(s int) string {
	if s >= 0 && s < len(condStatenames) {
		if condStatenames[s] != "" {
			return condStatenames[s]
		}
	}
	return __yyfmt__.Sprintf("state-%v", s)
}

func condErrorMessage(state, lookAhead int) string {
	const TOKSTART = 4

	if !condErrorVerbose {
		return "syntax error"
	}

	for _, e := range condErrorMessages {
		if e.state == state && e.token == lookAhead {
			return "syntax error: " + e.msg
		}
	}

	res := "syntax error: unexpected " + condTokname(lookAhead)

	// To match Bison, suggest at most four expected tokens.
	expected := make([]int, 0, 4)

	// Look for shiftable tokens.
	base := int(condPact[state])
	for tok := TOKSTART; tok-1 < len(condToknames); tok++ {
		if n := base + tok; n >= 0 && n < condLast && int(condChk[int(condAct[n])]) == tok {
			if len(expected) == cap(expected) {
				return res
			}
			expected = append(expected, tok)
		}
	}

	if condDef[state] == -2 {
		i := 0
		for condExca[i] != -1 || int(condExca[i+1]) != state {
			i += 2
		}

		// Look for tokens that we accept or reduce.
		for i += 2; condExca[i] >= 0; i += 2 {
			tok := int(condExca[i])
			if tok < TOKSTART || condExca[i+1] == 0 {
				continue
			}
			if len(expected) == cap(expected) {
				return res
			}
			expected = append(expected, tok)
		}

		// If the default action is to accept or reduce, give up.
		if condExca[i+1] != 0 {
			return res
		}
	}

	for i, tok := range expected {
		if i == 0 {
			res += ", expecting "
		} else {
			res += " or "
		}
		res += condTokname(tok)
	}
	return res
}

func condlex1(lex condLexer, lval *condSymType) (char, token int) {
	token = 0
	char = lex.Lex(lval)
	if char <= 0 {
		token = int(condTok1[0])
		goto out
	}
	if char < len(condTok1) {
		token = int(condTok1[char])
		goto out
	}
	if char >= condPrivate {
		if char < condPrivate+len(condTok2) {
			token = int(condTok2[char-condPrivate])
			goto out
		}
	}
	for i := 0; i < len(condTok3); i += 2 {
		token = int(condTok3[i+0])
		if token == char {
			token = int(condTok3[i+1])
			goto out
		}
	}

out:
	if token == 0 {
		token = int(condTok2[1]) /* unknown char */
	}
	if condDebug >= 3 {
		__yyfmt__.Printf("lex %s(%d)\n", condTokname(token), uint(char))
	}
	return char, token
}

func condParse(condlex condLexer) int {
	return condNewParser().Parse(condlex)
}

func (condrcvr *condParserImpl) Parse(condlex condLexer) int {
	var condn int
	var condVAL condSymType
	var condDollar []condSymType
	_ = condDollar // silence set and not used
	condS := condrcvr.stack[:]

	Nerrs := 0   /* number of errors */
	Errflag := 0 /* error recovery flag */
	condstate := 0
	condrcvr.char = -1
	condtoken := -1 // condrcvr.char translated into internal numbering
	defer func() {
		// Make sure we report no lookahead when not parsing.
		condstate = -1
		condrcvr.char = -1
		condtoken = -1
	}()
	condp := -1
	goto condstack

ret0:
	return 0

ret1:
	return 1

condstack:
	/* put a state and value onto the stack */
	if condDebug >= 4 {
		__yyfmt__.Printf("char %v in %v\n", condTokname(condtoken), condStatname(condstate))
	}

	condp++
	if condp >= len(condS) {
		nyys := make([]condSymType, len(condS)*2)
		copy(nyys, condS)
		condS = nyys
	}
	condS[condp] = condVAL
	condS[condp].yys = condstate

condnewstate:
	condn = int(condPact[condstate])
	if condn <= condFlag {
		goto conddefault /* simple state */
	}
	if condrcvr.char < 0 {
		condrcvr.char, condtoken = condlex1(condlex, &condrcvr.lval)
	}
	condn += condtoken
	if condn < 0 || condn >= condLast {
		goto conddefault
	}
	condn = int(condAct[condn])
	if int(condChk[condn]) == condtoken { /* valid shift */
		condrcvr.char = -1
		condtoken = -1
		condVAL = condrcvr.lval
		condstate = condn
		if Errflag > 0 {
			Errflag--
		}
		goto condstack
	}

conddefault:
	/* default state action */
	condn = int(condDef[condstate])
	if condn == -2 {
		if condrcvr.char < 0 {
			condrcvr.char, condtoken = condlex1(condlex, &condrcvr.lval)
		}

		/* look through exception table */
		xi := 0
		for {
			if condExca[xi+0] == -1 && int(condExca[xi+1]) == condstate {
				break
			}
			xi += 2
		}
		for xi += 2; ; xi += 2 {
			condn = int(condExca[xi+0])
			if condn < 0 || condn == condtoken {
				break
			}
		}
		condn = int(condExca[xi+1])
		if condn < 0 {
			goto ret0
		}
	}
	if condn == 0 {
		/* error ... attempt to resume parsing */
		switch Errflag {
		case 0: /* brand new error */
			condlex.Error(condErrorMessage(condstate, condtoken))
			Nerrs++
			if condDebug >= 1 {
				__yyfmt__.Printf("%s", condStatname(condstate))
				__yyfmt__.Printf(" saw %s\n", condTokname(condtoken))
			}
			fallthrough

		case 1, 2: /* incompletely recovered error ... try again */
			Errflag = 3

			/* find a state where "error" is a legal shift action */
			for condp >= 0 {
				condn = int(condPact[condS[condp].yys]) + condErrCode
				if condn >= 0 && condn < condLast {
					condstate = int(condAct[condn]) /* simulate a shift of "error" */
					if int(condChk[condstate]) == condErrCode {
						goto condstack
					}
				}

				/* the current p has no shift on "error", pop stack */
				if condDebug >= 2 {
					__yyfmt__.Printf("error recovery pops state %d\n", condS[condp].yys)
				}
				condp--
			}
			/* there is no state on the stack with an error shift ... abort */
			goto ret1

		case 3: /* no shift yet; clobber input char */
			if condDebug >= 2 {
				__yyfmt__.Printf("error recovery discards %s\n", condTokname(condtoken))
			}
			if condtoken == condEofCode {
				goto ret1
			}
			condrcvr.char = -1
			condtoken = -1
			goto condnewstate /* try again in the same state */
		}
	}

	/* reduction by production condn */
	if condDebug >= 2 {
		__yyfmt__.Printf("reduce %v in:\n\t%v\n", condn, condStatname(condstate))
	}

	condnt := condn
	condpt := condp
	_ = condpt // guard against "declared and not used"

	condp -= int(condR2[condn])
	// condp is now the index of $0. Perform the default action. Iff the
	// reduced production is ε, $1 is possibly out of range.
	if condp+1 >= len(condS) {
		nyys := make([]condSymType, len(condS)*2)
		copy(nyys, condS)
		condS = nyys
	}
	condVAL = condS[condp+1]

	/* consult goto table to find next state */
	condn = int(condR1[condn])
	condg := int(condPgo[condn])
	condj := condg + condS[condp].yys + 1

	if condj >= condLast {
		condstate = int(condAct[condg])
	} else {
		condstate = int(condAct[condj])
		if int(condChk[condstate]) != -condn {
			condstate = int(condAct[condg])
		}
	}
	// dummy call; replaced with literal code
	switch condnt {

	case 1:
		condDollar = condS[condpt-1 : condpt+1]
//line cond.y:45
		{
			parseNode = condDollar[1].Node
		}
	case 2:
		condDollar = condS[condpt-3 : condpt+1]
//line cond.y:50
		{
			condVAL.Node = &ParenExpr{condDollar[2].Node.(Expr)}

		}
	case 3:
		condDollar = condS[condpt-3 : condpt+1]
//line cond.y:55
		{
			condVAL.Node = &BinaryExpr{condDollar[1].Node.(Expr), LAND, condDollar[3].Node.(Expr)}
		}
	case 4:
		condDollar = condS[condpt-3 : condpt+1]
//line cond.y:59
		{
			condVAL.Node = &BinaryExpr{condDollar[1].Node.(Expr), LOR, condDollar[3].Node.(Expr)}
		}
	case 5:
		condDollar = condS[condpt-2 : condpt+1]
//line cond.y:63
		{
			condVAL.Node = &UnaryExpr{condDollar[2].Node.(Expr), NOT, lastTokenPos}
		}
	case 6:
		condDollar = condS[condpt-1 : condpt+1]
//line cond.y:67
		{
			condVAL.Node = condDollar[1].Node
		}
	case 7:
		condDollar = condS[condpt-1 : condpt+1]
//line cond.y:71
		{
			condVAL.Node = condDollar[1].Node
		}
	case 8:
		condDollar = condS[condpt-4 : condpt+1]
//line cond.y:77
		{
			condVAL.Node = &CallExpr{condDollar[1].Node.(*Ident), condDollar[3].Node.(BasicLitList), lastPos}
		}
	case 9:
		condDollar = condS[condpt-3 : condpt+1]
//line cond.y:81
		{
			condVAL.Node = &CallExpr{condDollar[1].Node.(*Ident), nil, lastPos}
		}
	case 10:
		condDollar = condS[condpt-1 : condpt+1]
//line cond.y:87
		{
			condVAL.Node = BasicLitList{condDollar[1].Node.(*BasicLit)}
		}
	case 11:
		condDollar = condS[condpt-3 : condpt+1]
//line cond.y:91
		{
			condVAL.Node = append(condDollar[1].Node.(BasicLitList), condDollar[3].Node.(*BasicLit))
		}
	}
	goto condstack /* stack new state and value */
}
