lang: Error parser if SetType fails to avoid a panic

Turns out we can actually cause the parser to error instead of needing
to panic. It definitely seems to work, and is better than the panic. The
only awkward thing is how this plumbing works in yacc world. If anyone
knows why this is wrong, please let me know. Reading the generated code
seems to imply that this is correct.
This commit is contained in:
James Shubin
2018-05-22 20:02:50 -04:00
parent a049af6262
commit 9cae339546
3 changed files with 29 additions and 1 deletions

View File

@@ -31,6 +31,7 @@ const (
ErrLexerIntegerOverflow = interfaces.Error("integer: overflow")
ErrLexerFloatOverflow = interfaces.Error("float: overflow")
ErrParseError = interfaces.Error("parser")
ErrParseSetType = interfaces.Error("can't set return type in parser")
ErrParseAdditionalEquals = interfaces.Error(errstrParseAdditionalEquals)
ErrParseExpectingComma = interfaces.Error(errstrParseExpectingComma)
)

View File

@@ -835,6 +835,30 @@ func TestLexParse0(t *testing.T) {
exp: exp,
})
}
{
values = append(values, test{
name: "parser set type incompatibility str",
code: `
$x int = "hello" # type should be str to work
test "t1" {
str => $x,
}
`,
fail: true,
})
}
{
values = append(values, test{
name: "parser set type incompatibility int",
code: `
$x int = "hello" # value should be int to work
test "t1" {
int => $x,
}
`,
fail: true,
})
}
for index, test := range values { // run all the tests
name, code, fail, exp := test.name, test.code, test.fail, test.exp

View File

@@ -637,7 +637,8 @@ bind:
posLast(yylex, yyDollar) // our pos
var expr interfaces.Expr = $4.expr
if err := expr.SetType($2.typ); err != nil {
panic(fmt.Sprintf("can't set type in parser: %+v", err))
// this will ultimately cause a parser error to occur...
yylex.Error(fmt.Sprintf("%s: %+v", ErrParseSetType, err))
}
$$.stmt = &StmtBind{
Ident: $1.str,
@@ -926,6 +927,8 @@ func (yylex *Lexer) Error(str string) {
err = ErrParseAdditionalEquals
} else if strings.HasSuffix(str, ErrParseExpectingComma.Error()) {
err = ErrParseExpectingComma
} else if strings.HasPrefix(str, ErrParseSetType.Error()) {
err = ErrParseSetType
}
lp.parseErr = &LexParseErr{
Err: err,