@@ -32,67 +32,68 @@ func (l *lexer) next() (*Token, error) {
32
32
for l .ch == ' ' || l .ch == '\n' || l .ch == '\t' {
33
33
l .nextch ()
34
34
}
35
+ var start = l .pos
35
36
switch l .ch {
36
37
case '"' :
37
38
return l .stringLiteral (l .ch )
38
39
case '\'' :
39
40
return l .stringLiteral (l .ch )
40
41
case '=' :
41
42
l .nextch ()
42
- return newToken (l . pos , l . pos , Equal , "=" ), nil
43
+ return newToken (start , start , Equal , "=" ), nil
43
44
case '!' :
44
45
l .nextch ()
45
- return newToken (l . pos , l . pos , Exclamation , "!" ), nil
46
+ return newToken (start , start , Exclamation , "!" ), nil
46
47
case ',' :
47
48
l .nextch ()
48
- return newToken (l . pos , l . pos , Comma , "," ), nil
49
+ return newToken (start , start , Comma , "," ), nil
49
50
case '(' :
50
51
l .nextch ()
51
- return newToken (l . pos , l . pos , ParenOpen , "(" ), nil
52
+ return newToken (start , start , ParenOpen , "(" ), nil
52
53
case ')' :
53
54
l .nextch ()
54
- return newToken (l . pos , l . pos , ParenClose , ")" ), nil
55
+ return newToken (start , start , ParenClose , ")" ), nil
55
56
case '{' :
56
57
l .nextch ()
57
- return newToken (l . pos , l . pos , BraceOpen , "{" ), nil
58
+ return newToken (start , start , BraceOpen , "{" ), nil
58
59
case '}' :
59
60
l .nextch ()
60
- return newToken (l . pos , l . pos , BraceClose , "}" ), nil
61
+ return newToken (start , start , BraceClose , "}" ), nil
61
62
case '[' :
62
63
l .nextch ()
63
- return newToken (l . pos , l . pos , BracketOpen , "[" ), nil
64
+ return newToken (start , start , BracketOpen , "[" ), nil
64
65
case ']' :
65
66
l .nextch ()
66
- return newToken (l . pos , l . pos , BracketClose , "]" ), nil
67
+ return newToken (start , start , BracketClose , "]" ), nil
67
68
case ':' :
68
69
l .nextch ()
69
- return newToken (l . pos , l . pos , Colon , ":" ), nil
70
+ return newToken (start , start , Colon , ":" ), nil
70
71
case ';' :
71
72
l .nextch ()
72
- return newToken (l . pos , l . pos , Semicolon , ";" ), nil
73
+ return newToken (start , start , Semicolon , ";" ), nil
73
74
case '+' :
74
75
l .nextch ()
75
- return newToken (l . pos , l . pos , Plus , "+" ), nil
76
+ return newToken (start , start , Plus , "+" ), nil
76
77
case '-' :
77
78
l .nextch ()
78
- return newToken (l . pos , l . pos , Minus , "-" ), nil
79
+ return newToken (start , start , Minus , "-" ), nil
79
80
case '*' :
80
81
l .nextch ()
81
- return newToken (l . pos , l . pos , Multiply , "*" ), nil
82
+ return newToken (start , start , Multiply , "*" ), nil
82
83
case '/' :
83
84
l .nextch ()
84
- return newToken (l . pos , l . pos , Divide , "/" ), nil
85
+ return newToken (start , start , Divide , "/" ), nil
85
86
case '$' :
86
87
return l .absoluteReference ()
87
88
case '&' :
88
89
l .nextch ()
89
- return newToken (l . pos , l . pos , Concat , "&" ), nil
90
+ return newToken (start , start , Concat , "&" ), nil
90
91
case '^' :
91
92
l .nextch ()
92
- return newToken (l . pos , l . pos , Exponentiation , "^" ), nil
93
+ return newToken (start , start , Exponentiation , "^" ), nil
93
94
case '%' :
94
95
l .nextch ()
95
- return newToken (l . pos , l . pos , Percent , "%" ), nil
96
+ return newToken (start , start , Percent , "%" ), nil
96
97
case '<' :
97
98
var start = l .pos
98
99
l .nextch ()
@@ -118,6 +119,9 @@ func (l *lexer) next() (*Token, error) {
118
119
}
119
120
case '#' :
120
121
return l .errValue ()
122
+ case '@' :
123
+ l .nextch ()
124
+ return newToken (start , start , ImplicitIntersection , "@" ), nil
121
125
default :
122
126
if isDigit (l .ch ) {
123
127
return l .number ()
@@ -224,16 +228,15 @@ func (l *lexer) errValue() (*Token, error) {
224
228
"#N/A" ,
225
229
}
226
230
for _ , value := range values {
231
+ _len := utf8 .RuneCountInString (value )
227
232
// check length
228
- if l .offset - 1 + len ( value ) > len (l .src ) {
233
+ if l .offset - 1 + _len > len (l .src ) {
229
234
continue // Not enough characters left for this error value
230
235
}
231
- if string (l .src [l .offset - 1 :l .offset - 1 + len ( value ) ]) == value {
236
+ if string (l .src [l .offset - 1 :l .offset - 1 + _len ]) == value {
232
237
var start = l .pos
233
- l .eat (len ( value ) - 1 ) // Consume the error value
238
+ l .eat (_len ) // Consume the error value
234
239
var end = l .pos
235
- l .offset += len (value ) - 1 // Adjust offset to skip the error value
236
- l .ch = l .peekChar () // Update current character
237
240
return newToken (start , end , EValue , value ), nil
238
241
}
239
242
}
@@ -244,25 +247,21 @@ func (l *lexer) stringLiteral(quote rune) (*Token, error) {
244
247
var start = l .pos
245
248
var end = start
246
249
l .nextch () // Consume the opening quote
247
- for l .ch != quote && l . ch >= 0 {
250
+ for l .ch >= 0 {
248
251
if l .ch == '\n' {
249
252
return nil , newLexError (l .pos , "newline in string literal" )
250
253
}
251
- if l .ch == '\\' {
252
- l .nextch ()
253
- switch {
254
- case l .ch < 0 :
255
- return nil , newLexError (l .pos , "unclosed string literal" )
256
- case l .ch == quote || l .ch == '\\' :
257
- // Consume the escaped character
258
- default :
259
- return nil , newLexError (l .pos , "invalid escape sequence in string literal" )
254
+ if l .ch == quote {
255
+ if l .peekChar () == quote {
256
+ l .nextch ()
257
+ } else {
258
+ break
260
259
}
261
260
}
262
261
end = l .pos
263
262
l .nextch ()
264
263
}
265
- if l .ch < 0 {
264
+ if l .ch != quote {
266
265
return nil , newLexError (l .pos , "unclosed string literal" )
267
266
}
268
267
end = l .pos // Update end to the position after the closing quote
@@ -315,7 +314,7 @@ func (l *lexer) ident() (*Token, error) {
315
314
LOOP:
316
315
for l .ch >= 0 {
317
316
switch {
318
- case isASCIILetter (l .ch ) || isDigit (l .ch ):
317
+ case isASCIILetter (l .ch ) || isDigit (l .ch ) || l . ch == '.' :
319
318
end = l .pos
320
319
endOffset = l .offset
321
320
l .nextch ()
0 commit comments