Item has line and column numbers
This commit is contained in:
parent
72f1734218
commit
eb86a5613d
@ -27,6 +27,8 @@ type (
|
|||||||
Token Token // The type of this item
|
Token Token // The type of this item
|
||||||
Val string // The value of this item
|
Val string // The value of this item
|
||||||
Pos int // The starting position, in bytes, of this item in the input string
|
Pos int // The starting position, in bytes, of this item in the input string
|
||||||
|
Line int // Line number
|
||||||
|
Column int // Column number
|
||||||
}
|
}
|
||||||
|
|
||||||
// Identifies the type of the item
|
// Identifies the type of the item
|
||||||
@ -86,6 +88,7 @@ func (l *Lexer) next() rune {
|
|||||||
l.width = 0
|
l.width = 0
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
r, w := utf8.DecodeRuneInString(l.input[l.pos:])
|
r, w := utf8.DecodeRuneInString(l.input[l.pos:])
|
||||||
l.width = w
|
l.width = w
|
||||||
l.pos += l.width
|
l.pos += l.width
|
||||||
@ -123,13 +126,17 @@ func (l *Lexer) acceptString(s string) (ok bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Steps back one rune
|
// Steps back one rune
|
||||||
|
// Backup is never called right after a new line char so we don't care
|
||||||
|
// about the line number. This is also true for the ignore function
|
||||||
func (l *Lexer) backup() {
|
func (l *Lexer) backup() {
|
||||||
l.pos -= l.width
|
l.pos -= l.width
|
||||||
|
l.colNum--
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skips over the pending input before this point
|
// Skips over the pending input before this point
|
||||||
func (l *Lexer) ignore() {
|
func (l *Lexer) ignore() {
|
||||||
l.start = l.pos
|
l.start = l.pos
|
||||||
|
l.startCol = l.colNum
|
||||||
}
|
}
|
||||||
|
|
||||||
// Passes an item back to the client
|
// Passes an item back to the client
|
||||||
@ -138,8 +145,10 @@ func (l *Lexer) emit(t Token) {
|
|||||||
Token: t,
|
Token: t,
|
||||||
Val: l.input[l.start:l.pos],
|
Val: l.input[l.start:l.pos],
|
||||||
Pos: l.start,
|
Pos: l.start,
|
||||||
|
Line: l.lineNum,
|
||||||
|
Column: l.startCol,
|
||||||
}
|
}
|
||||||
l.start = l.pos
|
l.ignore() // Cleaning up input
|
||||||
if t == EOF {
|
if t == EOF {
|
||||||
close(l.items)
|
close(l.items)
|
||||||
}
|
}
|
||||||
@ -151,6 +160,8 @@ func (l *Lexer) errorf(format string, args ...interface{}) stateFn {
|
|||||||
Token: Error,
|
Token: Error,
|
||||||
Val: fmt.Sprintf(format, args...),
|
Val: fmt.Sprintf(format, args...),
|
||||||
Pos: l.start,
|
Pos: l.start,
|
||||||
|
Line: l.lineNum,
|
||||||
|
Column: l.startCol,
|
||||||
}
|
}
|
||||||
close(l.items)
|
close(l.items)
|
||||||
return nil
|
return nil
|
||||||
@ -266,34 +277,37 @@ func lexString(l *Lexer) stateFn {
|
|||||||
//
|
//
|
||||||
|
|
||||||
func (i Item) String() string {
|
func (i Item) String() string {
|
||||||
|
var label string
|
||||||
switch i.Token {
|
switch i.Token {
|
||||||
case EOF:
|
case EOF:
|
||||||
return "EOF"
|
label = "EOF"
|
||||||
case Error:
|
case Error:
|
||||||
return fmt.Sprintf("(Error: %q)", i.Val)
|
label = fmt.Sprintf("(Error: %q)", i.Val)
|
||||||
case BraceOpen:
|
case BraceOpen:
|
||||||
return "{"
|
label = "{"
|
||||||
case BraceClose:
|
case BraceClose:
|
||||||
return "}"
|
label = "}"
|
||||||
case BracketOpen:
|
case BracketOpen:
|
||||||
return "["
|
label = "["
|
||||||
case BracketClose:
|
case BracketClose:
|
||||||
return "]"
|
label = "]"
|
||||||
case Quote:
|
case Quote:
|
||||||
return "\""
|
label = "\""
|
||||||
case Colon:
|
case Colon:
|
||||||
return ":"
|
label = ":"
|
||||||
case Comma:
|
case Comma:
|
||||||
return ","
|
label = ","
|
||||||
case Null:
|
case Null:
|
||||||
return fmt.Sprintf("(NULL: %q)", i.Val)
|
label = fmt.Sprintf("(NULL: %q)", i.Val)
|
||||||
case Bool:
|
case Bool:
|
||||||
return fmt.Sprintf("(Bool: %q)", i.Val)
|
label = fmt.Sprintf("(Bool: %q)", i.Val)
|
||||||
case Number:
|
case Number:
|
||||||
return fmt.Sprintf("(Number: %q)", i.Val)
|
label = fmt.Sprintf("(Number: %q)", i.Val)
|
||||||
case String:
|
case String:
|
||||||
return fmt.Sprintf("(String: %q)", i.Val)
|
label = fmt.Sprintf("(String: %q)", i.Val)
|
||||||
default:
|
default:
|
||||||
panic("Unreachable")
|
panic("Unreachable")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("[%.3d:%.3d] %s", i.Line, i.Column, label)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user