parser.go (358 lines of code) (raw):
// Code generated by goyacc -p hyperkv -o parser.go -v bin/hyperkv.out kvp.y. DO NOT EDIT.
//line kvp.y:24
/*
Copyright © 2023 (c) Microsoft Corporation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package hyperkv
import __yyfmt__ "fmt"
//line kvp.y:47
type HyperkvItem struct {
Key string
Value string
}
//line kvp.y:55
type hyperkvSymType struct {
yys int
content string
entry *HyperkvItem
entries []*HyperkvItem
}
const str = 57346
const space = 57347
const eof = 57348
var hyperkvToknames = [...]string{
"$end",
"error",
"$unk",
"str",
"space",
"eof",
}
var hyperkvStatenames = [...]string{}
const hyperkvEofCode = 1
const hyperkvErrCode = 2
const hyperkvInitialStackSize = 16
//line kvp.y:85
//line yacctab:1
var hyperkvExca = [...]int8{
-1, 1,
1, -1,
-2, 0,
}
const hyperkvPrivate = 57344
const hyperkvLast = 10
var hyperkvAct = [...]int8{
4, 7, 2, 8, 6, 1, 3, 0, 0, 5,
}
var hyperkvPact = [...]int16{
-4, -1000, -1000, -4, -1, -1000, -3, -2, -1000,
}
var hyperkvPgo = [...]int8{
0, 6, 5,
}
var hyperkvR1 = [...]int8{
0, 2, 2, 1,
}
var hyperkvR2 = [...]int8{
0, 1, 2, 4,
}
var hyperkvChk = [...]int16{
-1000, -2, 6, -1, 4, -2, 5, 4, 5,
}
var hyperkvDef = [...]int8{
0, -2, 1, 0, 0, 2, 0, 0, 3,
}
var hyperkvTok1 = [...]int8{
1,
}
var hyperkvTok2 = [...]int8{
2, 3, 4, 5, 6,
}
var hyperkvTok3 = [...]int8{
0,
}
var hyperkvErrorMessages = [...]struct {
state int
token int
msg string
}{}
//line yaccpar:1
/* parser for yacc output */
var (
hyperkvDebug = 0
hyperkvErrorVerbose = false
)
type hyperkvLexer interface {
Lex(lval *hyperkvSymType) int
Error(s string)
}
type hyperkvParser interface {
Parse(hyperkvLexer) int
Lookahead() int
}
type hyperkvParserImpl struct {
lval hyperkvSymType
stack [hyperkvInitialStackSize]hyperkvSymType
char int
}
func (p *hyperkvParserImpl) Lookahead() int {
return p.char
}
func hyperkvNewParser() hyperkvParser {
return &hyperkvParserImpl{}
}
const hyperkvFlag = -1000
func hyperkvTokname(c int) string {
if c >= 1 && c-1 < len(hyperkvToknames) {
if hyperkvToknames[c-1] != "" {
return hyperkvToknames[c-1]
}
}
return __yyfmt__.Sprintf("tok-%v", c)
}
func hyperkvStatname(s int) string {
if s >= 0 && s < len(hyperkvStatenames) {
if hyperkvStatenames[s] != "" {
return hyperkvStatenames[s]
}
}
return __yyfmt__.Sprintf("state-%v", s)
}
func hyperkvErrorMessage(state, lookAhead int) string {
const TOKSTART = 4
if !hyperkvErrorVerbose {
return "syntax error"
}
for _, e := range hyperkvErrorMessages {
if e.state == state && e.token == lookAhead {
return "syntax error: " + e.msg
}
}
res := "syntax error: unexpected " + hyperkvTokname(lookAhead)
// To match Bison, suggest at most four expected tokens.
expected := make([]int, 0, 4)
// Look for shiftable tokens.
base := int(hyperkvPact[state])
for tok := TOKSTART; tok-1 < len(hyperkvToknames); tok++ {
if n := base + tok; n >= 0 && n < hyperkvLast && int(hyperkvChk[int(hyperkvAct[n])]) == tok {
if len(expected) == cap(expected) {
return res
}
expected = append(expected, tok)
}
}
if hyperkvDef[state] == -2 {
i := 0
for hyperkvExca[i] != -1 || int(hyperkvExca[i+1]) != state {
i += 2
}
// Look for tokens that we accept or reduce.
for i += 2; hyperkvExca[i] >= 0; i += 2 {
tok := int(hyperkvExca[i])
if tok < TOKSTART || hyperkvExca[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 hyperkvExca[i+1] != 0 {
return res
}
}
for i, tok := range expected {
if i == 0 {
res += ", expecting "
} else {
res += " or "
}
res += hyperkvTokname(tok)
}
return res
}
func hyperkvlex1(lex hyperkvLexer, lval *hyperkvSymType) (char, token int) {
token = 0
char = lex.Lex(lval)
if char <= 0 {
token = int(hyperkvTok1[0])
goto out
}
if char < len(hyperkvTok1) {
token = int(hyperkvTok1[char])
goto out
}
if char >= hyperkvPrivate {
if char < hyperkvPrivate+len(hyperkvTok2) {
token = int(hyperkvTok2[char-hyperkvPrivate])
goto out
}
}
for i := 0; i < len(hyperkvTok3); i += 2 {
token = int(hyperkvTok3[i+0])
if token == char {
token = int(hyperkvTok3[i+1])
goto out
}
}
out:
if token == 0 {
token = int(hyperkvTok2[1]) /* unknown char */
}
if hyperkvDebug >= 3 {
__yyfmt__.Printf("lex %s(%d)\n", hyperkvTokname(token), uint(char))
}
return char, token
}
func hyperkvParse(hyperkvlex hyperkvLexer) int {
return hyperkvNewParser().Parse(hyperkvlex)
}
func (hyperkvrcvr *hyperkvParserImpl) Parse(hyperkvlex hyperkvLexer) int {
var hyperkvn int
var hyperkvVAL hyperkvSymType
var hyperkvDollar []hyperkvSymType
_ = hyperkvDollar // silence set and not used
hyperkvS := hyperkvrcvr.stack[:]
Nerrs := 0 /* number of errors */
Errflag := 0 /* error recovery flag */
hyperkvstate := 0
hyperkvrcvr.char = -1
hyperkvtoken := -1 // hyperkvrcvr.char translated into internal numbering
defer func() {
// Make sure we report no lookahead when not parsing.
hyperkvstate = -1
hyperkvrcvr.char = -1
hyperkvtoken = -1
}()
hyperkvp := -1
goto hyperkvstack
ret0:
return 0
ret1:
return 1
hyperkvstack:
/* put a state and value onto the stack */
if hyperkvDebug >= 4 {
__yyfmt__.Printf("char %v in %v\n", hyperkvTokname(hyperkvtoken), hyperkvStatname(hyperkvstate))
}
hyperkvp++
if hyperkvp >= len(hyperkvS) {
nyys := make([]hyperkvSymType, len(hyperkvS)*2)
copy(nyys, hyperkvS)
hyperkvS = nyys
}
hyperkvS[hyperkvp] = hyperkvVAL
hyperkvS[hyperkvp].yys = hyperkvstate
hyperkvnewstate:
hyperkvn = int(hyperkvPact[hyperkvstate])
if hyperkvn <= hyperkvFlag {
goto hyperkvdefault /* simple state */
}
if hyperkvrcvr.char < 0 {
hyperkvrcvr.char, hyperkvtoken = hyperkvlex1(hyperkvlex, &hyperkvrcvr.lval)
}
hyperkvn += hyperkvtoken
if hyperkvn < 0 || hyperkvn >= hyperkvLast {
goto hyperkvdefault
}
hyperkvn = int(hyperkvAct[hyperkvn])
if int(hyperkvChk[hyperkvn]) == hyperkvtoken { /* valid shift */
hyperkvrcvr.char = -1
hyperkvtoken = -1
hyperkvVAL = hyperkvrcvr.lval
hyperkvstate = hyperkvn
if Errflag > 0 {
Errflag--
}
goto hyperkvstack
}
hyperkvdefault:
/* default state action */
hyperkvn = int(hyperkvDef[hyperkvstate])
if hyperkvn == -2 {
if hyperkvrcvr.char < 0 {
hyperkvrcvr.char, hyperkvtoken = hyperkvlex1(hyperkvlex, &hyperkvrcvr.lval)
}
/* look through exception table */
xi := 0
for {
if hyperkvExca[xi+0] == -1 && int(hyperkvExca[xi+1]) == hyperkvstate {
break
}
xi += 2
}
for xi += 2; ; xi += 2 {
hyperkvn = int(hyperkvExca[xi+0])
if hyperkvn < 0 || hyperkvn == hyperkvtoken {
break
}
}
hyperkvn = int(hyperkvExca[xi+1])
if hyperkvn < 0 {
goto ret0
}
}
if hyperkvn == 0 {
/* error ... attempt to resume parsing */
switch Errflag {
case 0: /* brand new error */
hyperkvlex.Error(hyperkvErrorMessage(hyperkvstate, hyperkvtoken))
Nerrs++
if hyperkvDebug >= 1 {
__yyfmt__.Printf("%s", hyperkvStatname(hyperkvstate))
__yyfmt__.Printf(" saw %s\n", hyperkvTokname(hyperkvtoken))
}
fallthrough
case 1, 2: /* incompletely recovered error ... try again */
Errflag = 3
/* find a state where "error" is a legal shift action */
for hyperkvp >= 0 {
hyperkvn = int(hyperkvPact[hyperkvS[hyperkvp].yys]) + hyperkvErrCode
if hyperkvn >= 0 && hyperkvn < hyperkvLast {
hyperkvstate = int(hyperkvAct[hyperkvn]) /* simulate a shift of "error" */
if int(hyperkvChk[hyperkvstate]) == hyperkvErrCode {
goto hyperkvstack
}
}
/* the current p has no shift on "error", pop stack */
if hyperkvDebug >= 2 {
__yyfmt__.Printf("error recovery pops state %d\n", hyperkvS[hyperkvp].yys)
}
hyperkvp--
}
/* there is no state on the stack with an error shift ... abort */
goto ret1
case 3: /* no shift yet; clobber input char */
if hyperkvDebug >= 2 {
__yyfmt__.Printf("error recovery discards %s\n", hyperkvTokname(hyperkvtoken))
}
if hyperkvtoken == hyperkvEofCode {
goto ret1
}
hyperkvrcvr.char = -1
hyperkvtoken = -1
goto hyperkvnewstate /* try again in the same state */
}
}
/* reduction by production hyperkvn */
if hyperkvDebug >= 2 {
__yyfmt__.Printf("reduce %v in:\n\t%v\n", hyperkvn, hyperkvStatname(hyperkvstate))
}
hyperkvnt := hyperkvn
hyperkvpt := hyperkvp
_ = hyperkvpt // guard against "declared and not used"
hyperkvp -= int(hyperkvR2[hyperkvn])
// hyperkvp is now the index of $0. Perform the default action. Iff the
// reduced production is ε, $1 is possibly out of range.
if hyperkvp+1 >= len(hyperkvS) {
nyys := make([]hyperkvSymType, len(hyperkvS)*2)
copy(nyys, hyperkvS)
hyperkvS = nyys
}
hyperkvVAL = hyperkvS[hyperkvp+1]
/* consult goto table to find next state */
hyperkvn = int(hyperkvR1[hyperkvn])
hyperkvg := int(hyperkvPgo[hyperkvn])
hyperkvj := hyperkvg + hyperkvS[hyperkvp].yys + 1
if hyperkvj >= hyperkvLast {
hyperkvstate = int(hyperkvAct[hyperkvg])
} else {
hyperkvstate = int(hyperkvAct[hyperkvj])
if int(hyperkvChk[hyperkvstate]) != -hyperkvn {
hyperkvstate = int(hyperkvAct[hyperkvg])
}
}
// dummy call; replaced with literal code
switch hyperkvnt {
case 1:
hyperkvDollar = hyperkvS[hyperkvpt-1 : hyperkvpt+1]
//line kvp.y:70
{
hyperkvVAL.entries = make([]*HyperkvItem, 0)
}
case 2:
hyperkvDollar = hyperkvS[hyperkvpt-2 : hyperkvpt+1]
//line kvp.y:74
{
hyperkvVAL.entries = append(hyperkvDollar[2].entries, hyperkvDollar[1].entry)
hyperkvlex.(*hyperkvLexerImpl).Result = hyperkvVAL.entries
}
case 3:
hyperkvDollar = hyperkvS[hyperkvpt-4 : hyperkvpt+1]
//line kvp.y:81
{
hyperkvVAL.entry = &HyperkvItem{Key: hyperkvDollar[1].content, Value: hyperkvDollar[3].content}
}
}
goto hyperkvstack /* stack new state and value */
}