1
0
Fork 0

Make lexer errors more verbose

This commit is contained in:
Gregory Eremin 2015-02-17 02:26:16 +07:00
parent 0ab1758dec
commit 76ee42a0a6
2 changed files with 20 additions and 9 deletions

View File

@ -88,6 +88,11 @@ func (l *Lexer) next() rune {
return r return r
} }
// Returns the value for the next token
func (l *Lexer) val() string {
return l.input[l.start:l.pos]
}
// Returns but does not consume the next rune in the input // Returns but does not consume the next rune in the input
func (l *Lexer) peek() rune { func (l *Lexer) peek() rune {
r := l.next() r := l.next()
@ -198,7 +203,7 @@ func lexNull(l *Lexer) stateFn {
if l.acceptString("null") { if l.acceptString("null") {
l.emit(Null) l.emit(Null)
} else { } else {
return l.errorf("Unexpected token") return l.errorf("Unexpected (null) token: %q", l.val())
} }
return lexInitial return lexInitial
} }
@ -206,6 +211,8 @@ func lexNull(l *Lexer) stateFn {
func lexBool(l *Lexer) stateFn { func lexBool(l *Lexer) stateFn {
if l.acceptString("true") || l.acceptString("false") { if l.acceptString("true") || l.acceptString("false") {
l.emit(Bool) l.emit(Bool)
} else {
return l.errorf("Unexpected (bool) token: %q", l.val())
} }
return lexInitial return lexInitial
} }
@ -225,7 +232,7 @@ func lexNumber(l *Lexer) stateFn {
default: default:
l.backup() l.backup()
if numDots > 1 || last == '.' { if numDots > 1 || last == '.' {
return l.errorf("Invalid number") return l.errorf("Invalid number: %q", l.val())
} }
l.emit(Number) l.emit(Number)
return lexInitial return lexInitial
@ -263,12 +270,16 @@ func lexString(l *Lexer) stateFn {
} }
} }
//
// Debug
//
func (i Item) String() string { func (i Item) String() string {
switch i.Token { switch i.Token {
case EOF: case EOF:
return "EOF" return "EOF"
case Error: case Error:
return "Error: " + i.Val return fmt.Sprintf("(Error: %q)", i.Val)
case BraceOpen: case BraceOpen:
return "{" return "{"
case BraceClose: case BraceClose:
@ -284,13 +295,13 @@ func (i Item) String() string {
case Comma: case Comma:
return "," return ","
case Null: case Null:
return "NULL" return fmt.Sprintf("(NULL: %q)", i.Val)
case Bool: case Bool:
return "Bool: " + i.Val return fmt.Sprintf("(Bool: %q)", i.Val)
case Number: case Number:
return "Number: " + i.Val return fmt.Sprintf("(Number: %q)", i.Val)
case String: case String:
return "String: " + i.Val return fmt.Sprintf("(String: %q)", i.Val)
default: default:
panic("Unreachable") panic("Unreachable")
} }

View File

@ -43,10 +43,10 @@ func TestNumber(t *testing.T) {
Item{EOF, "", 0}, Item{EOF, "", 0},
}) })
compare(t, lex("123.456.789"), []Item{ compare(t, lex("123.456.789"), []Item{
Item{Error, "Invalid number", 0}, Item{Error, `Invalid number: "123.456.789"`, 0},
}) })
compare(t, lex("123."), []Item{ compare(t, lex("123."), []Item{
Item{Error, "Invalid number", 0}, Item{Error, `Invalid number: "123."`, 0},
}) })
} }