@@ -13,6 +13,11 @@ func Lex(source *file.Source) ([]Token, error) {
13
13
input : source .Content (),
14
14
tokens : make ([]Token , 0 ),
15
15
}
16
+
17
+ l .loc = file.Location {1 , 0 }
18
+ l .prev = l .loc
19
+ l .startLoc = l .loc
20
+
16
21
for state := root ; state != nil ; {
17
22
state = state (l )
18
23
}
@@ -28,8 +33,10 @@ type lexer struct {
28
33
input string
29
34
state stateFn
30
35
tokens []Token
31
- start , end int // current position in input
32
- width int // last rune with
36
+ start , end int // current position in input
37
+ width int // last rune with
38
+ startLoc file.Location // start location
39
+ prev , loc file.Location // prev location of end location, end location
33
40
err * file.Error
34
41
}
35
42
@@ -43,6 +50,15 @@ func (l *lexer) next() rune {
43
50
r , w := utf8 .DecodeRuneInString (l .input [l .end :])
44
51
l .width = w
45
52
l .end += w
53
+
54
+ l .prev = l .loc
55
+ if r == '\n' {
56
+ l .loc .Line ++
57
+ l .loc .Column = 0
58
+ } else {
59
+ l .loc .Column ++
60
+ }
61
+
46
62
return r
47
63
}
48
64
@@ -54,6 +70,7 @@ func (l *lexer) peek() rune {
54
70
55
71
func (l * lexer ) backup () {
56
72
l .end -= l .width
73
+ l .loc = l .prev
57
74
}
58
75
59
76
func (l * lexer ) emit (t Kind ) {
@@ -62,19 +79,21 @@ func (l *lexer) emit(t Kind) {
62
79
63
80
func (l * lexer ) emitValue (t Kind , value string ) {
64
81
l .tokens = append (l .tokens , Token {
65
- Location : l .loc ( l . start ) ,
82
+ Location : l .startLoc ,
66
83
Kind : t ,
67
84
Value : value ,
68
85
})
69
86
l .start = l .end
87
+ l .startLoc = l .loc
70
88
}
71
89
72
90
func (l * lexer ) emitEOF () {
73
91
l .tokens = append (l .tokens , Token {
74
- Location : l .loc ( l . start - 1 ) , // Point to previous position for better error messages.
92
+ Location : l .prev , // Point to previous position for better error messages.
75
93
Kind : EOF ,
76
94
})
77
95
l .start = l .end
96
+ l .startLoc = l .loc
78
97
}
79
98
80
99
func (l * lexer ) word () string {
@@ -83,6 +102,7 @@ func (l *lexer) word() string {
83
102
84
103
func (l * lexer ) ignore () {
85
104
l .start = l .end
105
+ l .startLoc = l .loc
86
106
}
87
107
88
108
func (l * lexer ) accept (valid string ) bool {
@@ -101,9 +121,13 @@ func (l *lexer) acceptRun(valid string) {
101
121
102
122
func (l * lexer ) acceptWord (word string ) bool {
103
123
pos := l .end
124
+ loc := l .loc
125
+ prev := l .prev
104
126
for _ , ch := range word {
105
127
if l .next () != ch {
106
128
l .end = pos
129
+ l .loc = loc
130
+ l .prev = prev
107
131
return false
108
132
}
109
133
}
@@ -113,32 +137,13 @@ func (l *lexer) acceptWord(word string) bool {
113
137
func (l * lexer ) error (format string , args ... interface {}) stateFn {
114
138
if l .err == nil { // show first error
115
139
l .err = & file.Error {
116
- Location : l .loc ( l . end - 1 ) ,
140
+ Location : l .loc ,
117
141
Message : fmt .Sprintf (format , args ... ),
118
142
}
119
143
}
120
144
return nil
121
145
}
122
146
123
- func (l * lexer ) loc (pos int ) file.Location {
124
- line , column := 1 , 0
125
- for i , ch := range []rune (l .input ) {
126
- if i == pos {
127
- break
128
- }
129
- if ch == '\n' {
130
- line ++
131
- column = 0
132
- } else {
133
- column ++
134
- }
135
- }
136
- return file.Location {
137
- Line : line ,
138
- Column : column ,
139
- }
140
- }
141
-
142
147
func digitVal (ch rune ) int {
143
148
switch {
144
149
case '0' <= ch && ch <= '9' :
0 commit comments