From 7e9fd3da5a19205f632ad0d07cde8df339810178 Mon Sep 17 00:00:00 2001 From: Ted van Riel <80752652+tvanriel@users.noreply.github.com> Date: Sat, 4 Jun 2022 11:04:23 +0200 Subject: [PATCH] feat: better error display Errors generated by l.Error() will now be wrapped with "lexer(pos=line,pos): " to improve the developer experience. Fix: bbuck/go-lexer#6 Signed-off-by: Ted van Riel <80752652+tvanriel@users.noreply.github.com> --- lexer.go | 15 +++++++++++++-- lexer_test/lexer_test.go | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/lexer.go b/lexer.go index 286dde6..966acdc 100644 --- a/lexer.go +++ b/lexer.go @@ -28,7 +28,7 @@ package lexer import ( - "errors" + "fmt" "strings" "unicode/utf8" ) @@ -188,11 +188,22 @@ func (l *L) NextToken() (*Token, bool) { } } +// Get the line number and position in that line the lexer position is currently on. +func getPos(l *L) (int, int) { + untilNow := l.source[:l.position] + linenum := strings.Count(untilNow, "\n") + 1 + lastNewLineIndex := strings.LastIndex(untilNow, "\n") + posInLine := l.position - lastNewLineIndex + return linenum, posInLine +} + // Partial yyLexer implementation func (l *L) Error(e string) { if l.ErrorHandler != nil { - l.Err = errors.New(e) + + linenum, pos := getPos(l) + l.Err = fmt.Errorf("lexer (pos=%d,%d): %v", linenum, pos, e) l.ErrorHandler(e) } else { panic(e) diff --git a/lexer_test/lexer_test.go b/lexer_test/lexer_test.go index e56bdc8..7e67e12 100644 --- a/lexer_test/lexer_test.go +++ b/lexer_test/lexer_test.go @@ -197,7 +197,7 @@ func Test_LexerError(t *testing.T) { return } - if l.Err.Error() != "unexpected token '1'" { + if l.Err.Error() != "lexer (pos=1,2): unexpected token '1'" { t.Errorf("Expected specific message from error, but got %q", l.Err.Error()) return }