PromQL: Fix lexer error handling (#6958)

* PromQL: Fix lexer error handling

This fixes bugs in the handling of lexer errors that are only noticeable for users of the language server and caused https://github.com/prometheus-community/promql-langserver/issues/104 .

Signed-off-by: Tobias Guggenmos <tobias.guggenmos@uni-ulm.de>

* Add test for error position ranges

Signed-off-by: Tobias Guggenmos <tobias.guggenmos@uni-ulm.de>
pull/6995/head
Tobias Guggenmos 5 years ago committed by GitHub
parent 350f25eed3
commit 012161d90d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -242,6 +242,11 @@ func (p *parser) addParseErr(positionRange PositionRange, err error) {
func (p *parser) unexpected(context string, expected string) {
var errMsg strings.Builder
// Do not report lexer errors twice
if p.yyParser.lval.item.Typ == ERROR {
return
}
errMsg.WriteString("unexpected ")
errMsg.WriteString(p.yyParser.lval.item.desc())
@ -302,10 +307,15 @@ func (p *parser) Lex(lval *yySymType) int {
}
switch typ {
case ERROR:
p.addParseErrf(lval.item.PositionRange(), "%s", lval.item.Val)
p.InjectItem(0)
pos := PositionRange{
Start: p.lex.start,
End: Pos(len(p.lex.input)),
}
p.addParseErr(pos, errors.New(p.yyParser.lval.item.Val))
// Tells yacc that this is the end of input.
return 0
case EOF:
lval.item.Typ = EOF
p.InjectItem(0)

@ -2592,6 +2592,16 @@ func TestParseExpressions(t *testing.T) {
} else {
testutil.NotOk(t, err)
testutil.Assert(t, strings.Contains(err.Error(), test.errMsg), "unexpected error on input '%s', expected '%s', got '%s'", test.input, test.errMsg, err.Error())
errorList, ok := err.(ParseErrors)
testutil.Assert(t, ok, "unexpected error type")
for _, e := range errorList {
testutil.Assert(t, 0 <= e.PositionRange.Start, "parse error has negative position\nExpression '%s'\nError: %v", test.input, e)
testutil.Assert(t, e.PositionRange.Start <= e.PositionRange.End, "parse error has negative length\nExpression '%s'\nError: %v", test.input, e)
testutil.Assert(t, e.PositionRange.End <= Pos(len(test.input)), "parse error is not contained in input\nExpression '%s'\nError: %v", test.input, e)
}
}
}
}

Loading…
Cancel
Save