Commit e7d9f816 authored by Matthew Dempsky's avatar Matthew Dempsky

cmd/internal/gc, cmd/yacc: implement "expecting" syntax error messages

Bison includes suggestions about what tokens are expected in the
current state when there's only four or fewer of them.  For example:

  syntax error: unexpected literal 2.01, expecting semicolon or newline or }

This CL adds the same functionality to cmd/yacc, which fully restores
the previous error message behavior from Go 1.4.

Updates #9968.

Change-Id: I2c1a1677c6d829a829d812c05e8813aa8829d09c
Reviewed-on: https://go-review.googlesource.com/8494
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarRuss Cox <rsc@golang.org>
parent ee54d571
...@@ -162,18 +162,13 @@ func Yyerror(format string, args ...interface{}) { ...@@ -162,18 +162,13 @@ func Yyerror(format string, args ...interface{}) {
return return
} }
// TODO(mdempsky): Extend cmd/yacc's verbose error // The grammar has { and LBRACE but both show up as {.
// messages to suggest expected tokens like Bison: // Rewrite syntax error referring to "{ or {" to say just "{".
// "syntax error: unexpected literal 2.01, expecting semicolon or newline or }" // The grammar has ? and @ but only for reading imports.
if false { // Silence them in ordinary errors.
// The grammar has { and LBRACE but both show up as {. msg = strings.Replace(msg, "{ or {", "{", -1)
// Rewrite syntax error referring to "{ or {" to say just "{". msg = strings.Replace(msg, " or ?", "", -1)
// The grammar has ? and @ but only for reading imports. msg = strings.Replace(msg, " or @", "", -1)
// Silence them in ordinary errors.
msg = strings.Replace(msg, "{ or {", "{", -1)
msg = strings.Replace(msg, " or ?", "", -1)
msg = strings.Replace(msg, " or @", "", -1)
}
msg = strings.Replace(msg, "LLITERAL", litbuf, -1) msg = strings.Replace(msg, "LLITERAL", litbuf, -1)
......
...@@ -912,6 +912,63 @@ func yyStatname(s int) string { ...@@ -912,6 +912,63 @@ func yyStatname(s int) string {
return __yyfmt__.Sprintf("state-%v", s) return __yyfmt__.Sprintf("state-%v", s)
} }
func yyErrorMessage(state, lookAhead int) string {
const TOKSTART = 4
if !yyErrorVerbose {
return "syntax error"
}
res := "syntax error: unexpected " + yyTokname(lookAhead)
// To match Bison, suggest at most four expected tokens.
expected := make([]int, 0, 4)
// Look for shiftable tokens.
base := yyPact[state]
for tok := TOKSTART; tok-1 < len(yyToknames); tok++ {
if n := base + tok; n >= 0 && n < yyLast && yyChk[yyAct[n]] == tok {
if len(expected) == cap(expected) {
return res
}
expected = append(expected, tok)
}
}
if yyDef[state] == -2 {
i := 0
for yyExca[i] != -1 || yyExca[i+1] != state {
i += 2
}
// Look for tokens that we accept or reduce.
for i += 2; yyExca[i] >= 0; i += 2 {
tok := yyExca[i]
if tok < TOKSTART || yyExca[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 yyExca[i+1] != 0 {
return res
}
}
for i, tok := range expected {
if i == 0 {
res += ", expecting "
} else {
res += " or "
}
res += yyTokname(tok)
}
return res
}
func yylex1(lex yyLexer, lval *yySymType) (char, token int) { func yylex1(lex yyLexer, lval *yySymType) (char, token int) {
token = 0 token = 0
char = lex.Lex(lval) char = lex.Lex(lval)
...@@ -1050,11 +1107,7 @@ yydefault: ...@@ -1050,11 +1107,7 @@ yydefault:
/* error ... attempt to resume parsing */ /* error ... attempt to resume parsing */
switch Errflag { switch Errflag {
case 0: /* brand new error */ case 0: /* brand new error */
yyErrMsg := "syntax error" yylex.Error(yyErrorMessage(yystate, yytoken))
if yyErrorVerbose {
yyErrMsg += ": unexpected " + yyTokname(yytoken)
}
yylex.Error(yyErrMsg)
Nerrs++ Nerrs++
if yyDebug >= 1 { if yyDebug >= 1 {
__yyfmt__.Printf("%s", yyStatname(yystate)) __yyfmt__.Printf("%s", yyStatname(yystate))
...@@ -1292,8 +1345,6 @@ yydefault: ...@@ -1292,8 +1345,6 @@ yydefault:
Yyerror("empty top-level declaration") Yyerror("empty top-level declaration")
yyVAL.list = nil yyVAL.list = nil
} }
case 24:
yyVAL.list = yyS[yypt-0].list
case 25: case 25:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line go.y:292 //line go.y:292
...@@ -1416,8 +1467,6 @@ yydefault: ...@@ -1416,8 +1467,6 @@ yydefault:
{ {
yyVAL.list = constiter(yyDollar[1].list, nil, yyDollar[3].list) yyVAL.list = constiter(yyDollar[1].list, nil, yyDollar[3].list)
} }
case 44:
yyVAL.list = yyS[yypt-0].list
case 45: case 45:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line go.y:387 //line go.y:387
...@@ -1717,8 +1766,6 @@ yydefault: ...@@ -1717,8 +1766,6 @@ yydefault:
yyVAL.node = Nod(OFOR, nil, nil) yyVAL.node = Nod(OFOR, nil, nil)
yyVAL.node.Ntest = yyDollar[1].node yyVAL.node.Ntest = yyDollar[1].node
} }
case 72:
yyVAL.node = yyS[yypt-0].node
case 73: case 73:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line go.y:654 //line go.y:654
...@@ -1880,8 +1927,6 @@ yydefault: ...@@ -1880,8 +1927,6 @@ yydefault:
yyVAL.node.List = yyDollar[4].list yyVAL.node.List = yyDollar[4].list
typesw = typesw.Left typesw = typesw.Left
} }
case 93:
yyVAL.node = yyS[yypt-0].node
case 94: case 94:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line go.y:796 //line go.y:796
...@@ -2002,8 +2047,6 @@ yydefault: ...@@ -2002,8 +2047,6 @@ yydefault:
{ {
yyVAL.node = Nod(OSEND, yyDollar[1].node, yyDollar[3].node) yyVAL.node = Nod(OSEND, yyDollar[1].node, yyDollar[3].node)
} }
case 114:
yyVAL.node = yyS[yypt-0].node
case 115: case 115:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line go.y:880 //line go.y:880
...@@ -2087,8 +2130,6 @@ yydefault: ...@@ -2087,8 +2130,6 @@ yydefault:
{ {
yyVAL.node = nodlit(yyDollar[1].val) yyVAL.node = nodlit(yyDollar[1].val)
} }
case 127:
yyVAL.node = yyS[yypt-0].node
case 128: case 128:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line go.y:948 //line go.y:948
...@@ -2138,8 +2179,6 @@ yydefault: ...@@ -2138,8 +2179,6 @@ yydefault:
} }
yyVAL.node = Nod(OSLICE3, yyDollar[1].node, Nod(OKEY, yyDollar[3].node, Nod(OKEY, yyDollar[5].node, yyDollar[7].node))) yyVAL.node = Nod(OSLICE3, yyDollar[1].node, Nod(OKEY, yyDollar[3].node, Nod(OKEY, yyDollar[5].node, yyDollar[7].node)))
} }
case 134:
yyVAL.node = yyS[yypt-0].node
case 135: case 135:
yyDollar = yyS[yypt-5 : yypt+1] yyDollar = yyS[yypt-5 : yypt+1]
//line go.y:986 //line go.y:986
...@@ -2174,8 +2213,6 @@ yydefault: ...@@ -2174,8 +2213,6 @@ yydefault:
yyVAL.node.Right = yyDollar[2].node yyVAL.node.Right = yyDollar[2].node
yyVAL.node.List = yyDollar[6].list yyVAL.node.List = yyDollar[6].list
} }
case 139:
yyVAL.node = yyS[yypt-0].node
case 140: case 140:
yyDollar = yyS[yypt-0 : yypt+1] yyDollar = yyS[yypt-0 : yypt+1]
//line go.y:1014 //line go.y:1014
...@@ -2212,8 +2249,6 @@ yydefault: ...@@ -2212,8 +2249,6 @@ yydefault:
yyVAL.node = yyDollar[2].node yyVAL.node = yyDollar[2].node
yyVAL.node.List = yyDollar[3].list yyVAL.node.List = yyDollar[3].list
} }
case 144:
yyVAL.node = yyS[yypt-0].node
case 145: case 145:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line go.y:1049 //line go.y:1049
...@@ -2221,8 +2256,6 @@ yydefault: ...@@ -2221,8 +2256,6 @@ yydefault:
yyVAL.node = yyDollar[2].node yyVAL.node = yyDollar[2].node
yyVAL.node.List = yyDollar[3].list yyVAL.node.List = yyDollar[3].list
} }
case 146:
yyVAL.node = yyS[yypt-0].node
case 147: case 147:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line go.y:1057 //line go.y:1057
...@@ -2237,12 +2270,6 @@ yydefault: ...@@ -2237,12 +2270,6 @@ yydefault:
yyVAL.node = Nod(OPAREN, yyVAL.node, nil) yyVAL.node = Nod(OPAREN, yyVAL.node, nil)
} }
} }
case 148:
yyVAL.node = yyS[yypt-0].node
case 149:
yyVAL.node = yyS[yypt-0].node
case 150:
yyVAL.node = yyS[yypt-0].node
case 151: case 151:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line go.y:1078 //line go.y:1078
...@@ -2277,8 +2304,6 @@ yydefault: ...@@ -2277,8 +2304,6 @@ yydefault:
{ {
yyVAL.node = nil yyVAL.node = nil
} }
case 156:
yyVAL.node = yyS[yypt-0].node
case 157: case 157:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line go.y:1115 //line go.y:1115
...@@ -2289,8 +2314,6 @@ yydefault: ...@@ -2289,8 +2314,6 @@ yydefault:
yyVAL.sym = Pkglookup(yyDollar[1].sym.Name, builtinpkg) yyVAL.sym = Pkglookup(yyDollar[1].sym.Name, builtinpkg)
} }
} }
case 158:
yyVAL.sym = yyS[yypt-0].sym
case 159: case 159:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line go.y:1124 //line go.y:1124
...@@ -2338,8 +2361,6 @@ yydefault: ...@@ -2338,8 +2361,6 @@ yydefault:
yyVAL.node.Pack.Used = true yyVAL.node.Pack.Used = true
} }
} }
case 163:
yyVAL.node = yyS[yypt-0].node
case 164: case 164:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line go.y:1181 //line go.y:1181
...@@ -2353,66 +2374,24 @@ yydefault: ...@@ -2353,66 +2374,24 @@ yydefault:
{ {
yyVAL.node = Nod(ODDD, yyDollar[2].node, nil) yyVAL.node = Nod(ODDD, yyDollar[2].node, nil)
} }
case 166:
yyVAL.node = yyS[yypt-0].node
case 167:
yyVAL.node = yyS[yypt-0].node
case 168:
yyVAL.node = yyS[yypt-0].node
case 169:
yyVAL.node = yyS[yypt-0].node
case 170:
yyVAL.node = yyS[yypt-0].node
case 171: case 171:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line go.y:1197 //line go.y:1197
{ {
yyVAL.node = yyDollar[2].node yyVAL.node = yyDollar[2].node
} }
case 172:
yyVAL.node = yyS[yypt-0].node
case 173:
yyVAL.node = yyS[yypt-0].node
case 174:
yyVAL.node = yyS[yypt-0].node
case 175: case 175:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line go.y:1206 //line go.y:1206
{ {
yyVAL.node = Nod(OIND, yyDollar[2].node, nil) yyVAL.node = Nod(OIND, yyDollar[2].node, nil)
} }
case 176:
yyVAL.node = yyS[yypt-0].node
case 177:
yyVAL.node = yyS[yypt-0].node
case 178:
yyVAL.node = yyS[yypt-0].node
case 179:
yyVAL.node = yyS[yypt-0].node
case 180: case 180:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line go.y:1216 //line go.y:1216
{ {
yyVAL.node = yyDollar[2].node yyVAL.node = yyDollar[2].node
} }
case 181:
yyVAL.node = yyS[yypt-0].node
case 182:
yyVAL.node = yyS[yypt-0].node
case 183:
yyVAL.node = yyS[yypt-0].node
case 184:
yyVAL.node = yyS[yypt-0].node
case 185:
yyVAL.node = yyS[yypt-0].node
case 186:
yyVAL.node = yyS[yypt-0].node
case 187:
yyVAL.node = yyS[yypt-0].node
case 188:
yyVAL.node = yyS[yypt-0].node
case 189:
yyVAL.node = yyS[yypt-0].node
case 190: case 190:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line go.y:1237 //line go.y:1237
...@@ -2459,10 +2438,6 @@ yydefault: ...@@ -2459,10 +2438,6 @@ yydefault:
{ {
yyVAL.node = Nod(OTMAP, yyDollar[3].node, yyDollar[5].node) yyVAL.node = Nod(OTMAP, yyDollar[3].node, yyDollar[5].node)
} }
case 196:
yyVAL.node = yyS[yypt-0].node
case 197:
yyVAL.node = yyS[yypt-0].node
case 198: case 198:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line go.y:1277 //line go.y:1277
...@@ -2721,16 +2696,12 @@ yydefault: ...@@ -2721,16 +2696,12 @@ yydefault:
nosplit = false nosplit = false
nowritebarrier = false nowritebarrier = false
} }
case 220:
yyVAL.list = yyS[yypt-0].list
case 221: case 221:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line go.y:1526 //line go.y:1526
{ {
yyVAL.list = concat(yyDollar[1].list, yyDollar[3].list) yyVAL.list = concat(yyDollar[1].list, yyDollar[3].list)
} }
case 222:
yyVAL.list = yyS[yypt-0].list
case 223: case 223:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line go.y:1533 //line go.y:1533
...@@ -2749,8 +2720,6 @@ yydefault: ...@@ -2749,8 +2720,6 @@ yydefault:
{ {
yyVAL.list = list(yyDollar[1].list, yyDollar[3].node) yyVAL.list = list(yyDollar[1].list, yyDollar[3].node)
} }
case 226:
yyVAL.list = yyS[yypt-0].list
case 227: case 227:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line go.y:1550 //line go.y:1550
...@@ -2899,8 +2868,6 @@ yydefault: ...@@ -2899,8 +2868,6 @@ yydefault:
yyVAL.node.List = yyDollar[2].list yyVAL.node.List = yyDollar[2].list
yyVAL.node.Rlist = yyDollar[4].list yyVAL.node.Rlist = yyDollar[4].list
} }
case 243:
yyVAL.node = yyS[yypt-0].node
case 244: case 244:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line go.y:1684 //line go.y:1684
...@@ -2917,8 +2884,6 @@ yydefault: ...@@ -2917,8 +2884,6 @@ yydefault:
yyVAL.node.Sym = yyDollar[1].sym yyVAL.node.Sym = yyDollar[1].sym
yyVAL.node = Nod(OKEY, yyVAL.node, yyDollar[2].node) yyVAL.node = Nod(OKEY, yyVAL.node, yyDollar[2].node)
} }
case 246:
yyVAL.node = yyS[yypt-0].node
case 247: case 247:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line go.y:1699 //line go.y:1699
...@@ -2949,32 +2914,18 @@ yydefault: ...@@ -2949,32 +2914,18 @@ yydefault:
{ {
yyVAL.node = nil yyVAL.node = nil
} }
case 252:
yyVAL.node = yyS[yypt-0].node
case 253: case 253:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line go.y:1725 //line go.y:1725
{ {
yyVAL.node = liststmt(yyDollar[1].list) yyVAL.node = liststmt(yyDollar[1].list)
} }
case 254:
yyVAL.node = yyS[yypt-0].node
case 255: case 255:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line go.y:1730 //line go.y:1730
{ {
yyVAL.node = nil yyVAL.node = nil
} }
case 256:
yyVAL.node = yyS[yypt-0].node
case 257:
yyVAL.node = yyS[yypt-0].node
case 258:
yyVAL.node = yyS[yypt-0].node
case 259:
yyVAL.node = yyS[yypt-0].node
case 260:
yyVAL.node = yyS[yypt-0].node
case 261: case 261:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line go.y:1741 //line go.y:1741
...@@ -3164,56 +3115,42 @@ yydefault: ...@@ -3164,56 +3115,42 @@ yydefault:
{ {
yyVAL.node = nil yyVAL.node = nil
} }
case 291:
yyVAL.node = yyS[yypt-0].node
case 292: case 292:
yyDollar = yyS[yypt-0 : yypt+1] yyDollar = yyS[yypt-0 : yypt+1]
//line go.y:1906 //line go.y:1906
{ {
yyVAL.list = nil yyVAL.list = nil
} }
case 293:
yyVAL.list = yyS[yypt-0].list
case 294: case 294:
yyDollar = yyS[yypt-0 : yypt+1] yyDollar = yyS[yypt-0 : yypt+1]
//line go.y:1912 //line go.y:1912
{ {
yyVAL.node = nil yyVAL.node = nil
} }
case 295:
yyVAL.node = yyS[yypt-0].node
case 296: case 296:
yyDollar = yyS[yypt-0 : yypt+1] yyDollar = yyS[yypt-0 : yypt+1]
//line go.y:1918 //line go.y:1918
{ {
yyVAL.list = nil yyVAL.list = nil
} }
case 297:
yyVAL.list = yyS[yypt-0].list
case 298: case 298:
yyDollar = yyS[yypt-0 : yypt+1] yyDollar = yyS[yypt-0 : yypt+1]
//line go.y:1924 //line go.y:1924
{ {
yyVAL.list = nil yyVAL.list = nil
} }
case 299:
yyVAL.list = yyS[yypt-0].list
case 300: case 300:
yyDollar = yyS[yypt-0 : yypt+1] yyDollar = yyS[yypt-0 : yypt+1]
//line go.y:1930 //line go.y:1930
{ {
yyVAL.list = nil yyVAL.list = nil
} }
case 301:
yyVAL.list = yyS[yypt-0].list
case 302: case 302:
yyDollar = yyS[yypt-0 : yypt+1] yyDollar = yyS[yypt-0 : yypt+1]
//line go.y:1936 //line go.y:1936
{ {
yyVAL.val.Ctype = CTxxx yyVAL.val.Ctype = CTxxx
} }
case 303:
yyVAL.val = yyS[yypt-0].val
case 304: case 304:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line go.y:1946 //line go.y:1946
...@@ -3279,16 +3216,6 @@ yydefault: ...@@ -3279,16 +3216,6 @@ yydefault:
yyVAL.typ = pkgtype(yyDollar[1].sym) yyVAL.typ = pkgtype(yyDollar[1].sym)
importsym(yyDollar[1].sym, OTYPE) importsym(yyDollar[1].sym, OTYPE)
} }
case 312:
yyVAL.typ = yyS[yypt-0].typ
case 313:
yyVAL.typ = yyS[yypt-0].typ
case 314:
yyVAL.typ = yyS[yypt-0].typ
case 315:
yyVAL.typ = yyS[yypt-0].typ
case 316:
yyVAL.typ = yyS[yypt-0].typ
case 317: case 317:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line go.y:2014 //line go.y:2014
...@@ -3451,8 +3378,6 @@ yydefault: ...@@ -3451,8 +3378,6 @@ yydefault:
{ {
yyVAL.list = nil yyVAL.list = nil
} }
case 336:
yyVAL.list = yyS[yypt-0].list
case 337: case 337:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line go.y:2152 //line go.y:2152
...@@ -3500,8 +3425,6 @@ yydefault: ...@@ -3500,8 +3425,6 @@ yydefault:
Yyerror("bad constant %v", Sconv(yyVAL.node.Sym, 0)) Yyerror("bad constant %v", Sconv(yyVAL.node.Sym, 0))
} }
} }
case 342:
yyVAL.node = yyS[yypt-0].node
case 343: case 343:
yyDollar = yyS[yypt-5 : yypt+1] yyDollar = yyS[yypt-5 : yypt+1]
//line go.y:2198 //line go.y:2198
......
...@@ -3212,7 +3212,7 @@ type $$Parser interface { ...@@ -3212,7 +3212,7 @@ type $$Parser interface {
type $$ParserImpl struct { type $$ParserImpl struct {
lookahead func() int lookahead func() int
state func() int state func() int
} }
func (p *$$ParserImpl) Lookahead() int { func (p *$$ParserImpl) Lookahead() int {
...@@ -3222,7 +3222,7 @@ func (p *$$ParserImpl) Lookahead() int { ...@@ -3222,7 +3222,7 @@ func (p *$$ParserImpl) Lookahead() int {
func $$NewParser() $$Parser { func $$NewParser() $$Parser {
p := &$$ParserImpl{ p := &$$ParserImpl{
lookahead: func() int { return -1 }, lookahead: func() int { return -1 },
state: func() int { return -1 }, state: func() int { return -1 },
} }
return p return p
} }
...@@ -3247,6 +3247,63 @@ func $$Statname(s int) string { ...@@ -3247,6 +3247,63 @@ func $$Statname(s int) string {
return __yyfmt__.Sprintf("state-%v", s) return __yyfmt__.Sprintf("state-%v", s)
} }
func $$ErrorMessage(state, lookAhead int) string {
const TOKSTART = 4
if !$$ErrorVerbose {
return "syntax error"
}
res := "syntax error: unexpected " + $$Tokname(lookAhead)
// To match Bison, suggest at most four expected tokens.
expected := make([]int, 0, 4)
// Look for shiftable tokens.
base := $$Pact[state]
for tok := TOKSTART; tok-1 < len($$Toknames); tok++ {
if n := base + tok; n >= 0 && n < $$Last && $$Chk[$$Act[n]] == tok {
if len(expected) == cap(expected) {
return res
}
expected = append(expected, tok)
}
}
if $$Def[state] == -2 {
i := 0
for $$Exca[i] != -1 || $$Exca[i+1] != state {
i += 2
}
// Look for tokens that we accept or reduce.
for i += 2; $$Exca[i] >= 0; i += 2 {
tok := $$Exca[i]
if tok < TOKSTART || $$Exca[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 $$Exca[i+1] != 0 {
return res
}
}
for i, tok := range expected {
if i == 0 {
res += ", expecting "
} else {
res += " or "
}
res += $$Tokname(tok)
}
return res
}
func $$lex1(lex $$Lexer, lval *$$SymType) (char, token int) { func $$lex1(lex $$Lexer, lval *$$SymType) (char, token int) {
token = 0 token = 0
char = lex.Lex(lval) char = lex.Lex(lval)
...@@ -3385,11 +3442,7 @@ $$default: ...@@ -3385,11 +3442,7 @@ $$default:
/* error ... attempt to resume parsing */ /* error ... attempt to resume parsing */
switch Errflag { switch Errflag {
case 0: /* brand new error */ case 0: /* brand new error */
$$ErrMsg := "syntax error" $$lex.Error($$ErrorMessage($$state, $$token))
if $$ErrorVerbose {
$$ErrMsg += ": unexpected " + $$Tokname($$token)
}
$$lex.Error($$ErrMsg)
Nerrs++ Nerrs++
if $$Debug >= 1 { if $$Debug >= 1 {
__yyfmt__.Printf("%s", $$Statname($$state)) __yyfmt__.Printf("%s", $$Statname($$state))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment