ether-code 0.8.7 → 0.8.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/ether.js +1 -1
- package/generators/php-generator.js +63 -3
- package/lexer/ether-lexer.js +387 -363
- package/package.json +1 -1
- package/parsers/ether-parser-base.js +9 -9
- package/parsers/ether-parser-php.js +179 -11
package/lexer/ether-lexer.js
CHANGED
|
@@ -31,6 +31,7 @@ const TokenType = {
|
|
|
31
31
|
SPREAD: 'SPREAD',
|
|
32
32
|
ARROW: 'ARROW',
|
|
33
33
|
FAT_ARROW: 'FAT_ARROW',
|
|
34
|
+
SEMICOLON: 'SEMICOLON',
|
|
34
35
|
|
|
35
36
|
PLUS: 'PLUS',
|
|
36
37
|
MINUS: 'MINUS',
|
|
@@ -75,7 +76,6 @@ const TokenType = {
|
|
|
75
76
|
|
|
76
77
|
COMMENT: 'COMMENT',
|
|
77
78
|
BLOCK_COMMENT: 'BLOCK_COMMENT',
|
|
78
|
-
SEMICOLON: 'SEMICOLON',
|
|
79
79
|
|
|
80
80
|
EOF: 'EOF',
|
|
81
81
|
ERROR: 'ERROR'
|
|
@@ -100,17 +100,20 @@ class EtherLexer {
|
|
|
100
100
|
this.indentStack = [0]
|
|
101
101
|
this.currentIndent = 0
|
|
102
102
|
this.atLineStart = true
|
|
103
|
+
this.options = options
|
|
104
|
+
this.lastTokenType = null
|
|
103
105
|
|
|
104
|
-
this.
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
106
|
+
this.compoundKeywordsCache = null
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
isAtEnd() {
|
|
110
|
+
return this.pos >= this.source.length
|
|
109
111
|
}
|
|
110
112
|
|
|
111
113
|
peek(offset = 0) {
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
+
const pos = this.pos + offset
|
|
115
|
+
if (pos >= this.source.length) return '\0'
|
|
116
|
+
return this.source[pos]
|
|
114
117
|
}
|
|
115
118
|
|
|
116
119
|
advance() {
|
|
@@ -119,7 +122,6 @@ class EtherLexer {
|
|
|
119
122
|
if (char === '\n') {
|
|
120
123
|
this.line++
|
|
121
124
|
this.column = 1
|
|
122
|
-
this.atLineStart = true
|
|
123
125
|
} else {
|
|
124
126
|
this.column++
|
|
125
127
|
}
|
|
@@ -127,65 +129,21 @@ class EtherLexer {
|
|
|
127
129
|
}
|
|
128
130
|
|
|
129
131
|
match(expected) {
|
|
130
|
-
if (this.
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
return false
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
matchSequence(seq) {
|
|
138
|
-
for (let i = 0; i < seq.length; i++) {
|
|
139
|
-
if (this.peek(i) !== seq[i]) return false
|
|
140
|
-
}
|
|
141
|
-
for (let i = 0; i < seq.length; i++) {
|
|
142
|
-
this.advance()
|
|
143
|
-
}
|
|
132
|
+
if (this.isAtEnd()) return false
|
|
133
|
+
if (this.source[this.pos] !== expected) return false
|
|
134
|
+
this.advance()
|
|
144
135
|
return true
|
|
145
136
|
}
|
|
146
137
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
isHexDigit(char) {
|
|
157
|
-
if (!char) return false
|
|
158
|
-
return this.isDigit(char) || (char >= 'a' && char <= 'f') || (char >= 'A' && char <= 'F')
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
isAlpha(char) {
|
|
162
|
-
if (!char) return false
|
|
163
|
-
const code = char.charCodeAt(0)
|
|
164
|
-
if ((code >= 65 && code <= 90) || (code >= 97 && code <= 122)) return true
|
|
165
|
-
if (char === '_') return true
|
|
166
|
-
if (this.options.allowUnicode) {
|
|
167
|
-
if (code >= 0x00C0 && code <= 0x024F) return true
|
|
168
|
-
if (code >= 0x0400 && code <= 0x04FF) return true
|
|
169
|
-
if (code >= 0x4E00 && code <= 0x9FFF) return true
|
|
170
|
-
if (code >= 0x3040 && code <= 0x30FF) return true
|
|
171
|
-
if (code >= 0x0600 && code <= 0x06FF) return true
|
|
172
|
-
if (code >= 0x0370 && code <= 0x03FF) return true
|
|
173
|
-
}
|
|
174
|
-
return false
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
isAlphaNumeric(char) {
|
|
178
|
-
return this.isAlpha(char) || this.isDigit(char)
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
isWhitespace(char) {
|
|
182
|
-
if (!char) return false
|
|
183
|
-
return char === ' ' || char === '\t' || char === '\r'
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
addToken(type, value, startColumn = null) {
|
|
187
|
-
const col = startColumn !== null ? startColumn : this.column
|
|
188
|
-
this.tokens.push(new Token(type, value, this.line, col, this.currentIndent))
|
|
138
|
+
skipWhitespace() {
|
|
139
|
+
while (!this.isAtEnd()) {
|
|
140
|
+
const char = this.peek()
|
|
141
|
+
if (char === ' ' || char === '\t' || char === '\r') {
|
|
142
|
+
this.advance()
|
|
143
|
+
} else {
|
|
144
|
+
break
|
|
145
|
+
}
|
|
146
|
+
}
|
|
189
147
|
}
|
|
190
148
|
|
|
191
149
|
tokenize() {
|
|
@@ -195,7 +153,7 @@ class EtherLexer {
|
|
|
195
153
|
|
|
196
154
|
while (this.indentStack.length > 1) {
|
|
197
155
|
this.indentStack.pop()
|
|
198
|
-
this.tokens.push(new Token(TokenType.DEDENT, '', this.line, this.column,
|
|
156
|
+
this.tokens.push(new Token(TokenType.DEDENT, '', this.line, this.column, this.currentIndent))
|
|
199
157
|
}
|
|
200
158
|
|
|
201
159
|
this.tokens.push(new Token(TokenType.EOF, '', this.line, this.column, 0))
|
|
@@ -205,34 +163,22 @@ class EtherLexer {
|
|
|
205
163
|
scanToken() {
|
|
206
164
|
if (this.atLineStart) {
|
|
207
165
|
this.handleIndentation()
|
|
208
|
-
|
|
166
|
+
this.atLineStart = false
|
|
209
167
|
}
|
|
210
168
|
|
|
211
|
-
|
|
169
|
+
this.skipWhitespace()
|
|
212
170
|
|
|
213
|
-
if (
|
|
214
|
-
this.advance()
|
|
215
|
-
this.addToken(TokenType.NEWLINE, '\n')
|
|
216
|
-
return
|
|
217
|
-
}
|
|
171
|
+
if (this.isAtEnd()) return
|
|
218
172
|
|
|
219
|
-
|
|
220
|
-
this.advance()
|
|
221
|
-
return
|
|
222
|
-
}
|
|
173
|
+
const char = this.peek()
|
|
223
174
|
|
|
224
|
-
if (char === '
|
|
225
|
-
|
|
226
|
-
if (next && (this.isHexDigit(next) || this.isAlpha(next))) {
|
|
227
|
-
this.scanHashToken()
|
|
228
|
-
return
|
|
229
|
-
}
|
|
230
|
-
this.scanComment()
|
|
175
|
+
if (char === '\n') {
|
|
176
|
+
this.handleNewline()
|
|
231
177
|
return
|
|
232
178
|
}
|
|
233
179
|
|
|
234
180
|
if (char === '/' && this.peek(1) === '/') {
|
|
235
|
-
this.
|
|
181
|
+
this.scanLineComment()
|
|
236
182
|
return
|
|
237
183
|
}
|
|
238
184
|
|
|
@@ -241,8 +187,13 @@ class EtherLexer {
|
|
|
241
187
|
return
|
|
242
188
|
}
|
|
243
189
|
|
|
190
|
+
if (char === '#') {
|
|
191
|
+
this.scanLineComment()
|
|
192
|
+
return
|
|
193
|
+
}
|
|
194
|
+
|
|
244
195
|
if (char === '"' || char === "'") {
|
|
245
|
-
this.scanString(
|
|
196
|
+
this.scanString()
|
|
246
197
|
return
|
|
247
198
|
}
|
|
248
199
|
|
|
@@ -251,24 +202,43 @@ class EtherLexer {
|
|
|
251
202
|
return
|
|
252
203
|
}
|
|
253
204
|
|
|
254
|
-
if (this.isDigit(char) || (char === '
|
|
205
|
+
if (this.isDigit(char) || (char === '.' && this.isDigit(this.peek(1)))) {
|
|
255
206
|
this.scanNumber()
|
|
256
207
|
return
|
|
257
208
|
}
|
|
258
209
|
|
|
259
|
-
if (this.isAlpha(char)) {
|
|
210
|
+
if (this.isAlpha(char) || char === '_' || char === '$') {
|
|
260
211
|
this.scanIdentifier()
|
|
261
212
|
return
|
|
262
213
|
}
|
|
263
214
|
|
|
264
|
-
this.
|
|
215
|
+
if (this.isOperator(char)) {
|
|
216
|
+
this.scanOperator()
|
|
217
|
+
return
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
this.advance()
|
|
221
|
+
this.tokens.push(new Token(TokenType.ERROR, `Caractère inattendu: ${char}`, this.line, this.column - 1, this.currentIndent))
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
handleNewline() {
|
|
225
|
+
const startLine = this.line
|
|
226
|
+
const startCol = this.column
|
|
227
|
+
this.advance()
|
|
228
|
+
|
|
229
|
+
while (!this.isAtEnd() && this.peek() === '\n') {
|
|
230
|
+
this.advance()
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
this.tokens.push(new Token(TokenType.NEWLINE, '\n', startLine, startCol, this.currentIndent))
|
|
234
|
+
this.atLineStart = true
|
|
265
235
|
}
|
|
266
236
|
|
|
267
237
|
handleIndentation() {
|
|
268
238
|
let indent = 0
|
|
269
239
|
while (!this.isAtEnd() && (this.peek() === ' ' || this.peek() === '\t')) {
|
|
270
240
|
if (this.peek() === '\t') {
|
|
271
|
-
indent +=
|
|
241
|
+
indent += 4
|
|
272
242
|
} else {
|
|
273
243
|
indent++
|
|
274
244
|
}
|
|
@@ -276,368 +246,238 @@ class EtherLexer {
|
|
|
276
246
|
}
|
|
277
247
|
|
|
278
248
|
if (this.isAtEnd() || this.peek() === '\n') {
|
|
279
|
-
this.atLineStart = false
|
|
280
249
|
return
|
|
281
250
|
}
|
|
282
|
-
|
|
283
|
-
if (this.peek() === '#') {
|
|
284
|
-
const next = this.peek(1)
|
|
285
|
-
if (!next || (!this.isAlpha(next) && !this.isHexDigit(next))) {
|
|
286
|
-
this.atLineStart = false
|
|
287
|
-
return
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
251
|
|
|
291
252
|
if (this.peek() === '/' && this.peek(1) === '/') {
|
|
292
|
-
this.atLineStart = false
|
|
293
253
|
return
|
|
294
254
|
}
|
|
295
255
|
|
|
296
|
-
this.
|
|
297
|
-
|
|
256
|
+
if (this.peek() === '#') {
|
|
257
|
+
return
|
|
258
|
+
}
|
|
298
259
|
|
|
299
260
|
const currentLevel = this.indentStack[this.indentStack.length - 1]
|
|
300
261
|
|
|
301
262
|
if (indent > currentLevel) {
|
|
302
263
|
this.indentStack.push(indent)
|
|
264
|
+
this.currentIndent = indent
|
|
303
265
|
this.tokens.push(new Token(TokenType.INDENT, indent, this.line, 1, indent))
|
|
304
266
|
} else if (indent < currentLevel) {
|
|
305
|
-
while (this.indentStack.length > 1 && this.indentStack[this.indentStack.length - 1]
|
|
267
|
+
while (this.indentStack.length > 1 && indent < this.indentStack[this.indentStack.length - 1]) {
|
|
306
268
|
this.indentStack.pop()
|
|
307
|
-
this.tokens.push(new Token(TokenType.DEDENT, '', this.line, 1,
|
|
308
|
-
}
|
|
309
|
-
if (this.indentStack[this.indentStack.length - 1] !== indent && indent > 0) {
|
|
310
|
-
this.indentStack.push(indent)
|
|
269
|
+
this.tokens.push(new Token(TokenType.DEDENT, '', this.line, 1, this.indentStack[this.indentStack.length - 1]))
|
|
311
270
|
}
|
|
271
|
+
this.currentIndent = this.indentStack[this.indentStack.length - 1]
|
|
312
272
|
}
|
|
313
273
|
}
|
|
314
274
|
|
|
315
|
-
|
|
275
|
+
scanLineComment() {
|
|
316
276
|
const startLine = this.line
|
|
317
277
|
const startCol = this.column
|
|
318
|
-
|
|
319
|
-
|
|
278
|
+
|
|
320
279
|
if (this.peek() === '#') {
|
|
321
280
|
this.advance()
|
|
322
281
|
} else {
|
|
323
282
|
this.advance()
|
|
324
283
|
this.advance()
|
|
325
284
|
}
|
|
326
|
-
|
|
327
|
-
while (!this.isAtEnd() && this.peek() !== '\n') {
|
|
328
|
-
comment += this.advance()
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
if (this.options.trackComments) {
|
|
332
|
-
this.tokens.push(new Token(TokenType.COMMENT, comment.trim(), startLine, startCol, this.currentIndent))
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
scanHashToken() {
|
|
337
|
-
const startLine = this.line
|
|
338
|
-
const startCol = this.column
|
|
339
|
-
|
|
340
|
-
this.advance()
|
|
341
285
|
|
|
342
286
|
let value = ''
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
while (!this.isAtEnd()) {
|
|
347
|
-
const char = this.peek()
|
|
348
|
-
if (this.isHexDigit(char)) {
|
|
349
|
-
value += this.advance()
|
|
350
|
-
charCount++
|
|
351
|
-
} else if (this.isAlpha(char) && !this.isHexDigit(char)) {
|
|
352
|
-
isHexColor = false
|
|
353
|
-
value += this.advance()
|
|
354
|
-
} else if (char === '-' || char === '_') {
|
|
355
|
-
isHexColor = false
|
|
356
|
-
value += this.advance()
|
|
357
|
-
} else {
|
|
358
|
-
break
|
|
359
|
-
}
|
|
287
|
+
while (!this.isAtEnd() && this.peek() !== '\n') {
|
|
288
|
+
value += this.advance()
|
|
360
289
|
}
|
|
361
290
|
|
|
362
|
-
|
|
363
|
-
this.tokens.push(new Token(TokenType.HEX, '#' + value, startLine, startCol, this.currentIndent))
|
|
364
|
-
} else {
|
|
365
|
-
this.tokens.push(new Token(TokenType.HASH, '#', startLine, startCol, this.currentIndent))
|
|
366
|
-
if (value) {
|
|
367
|
-
this.tokens.push(new Token(TokenType.IDENTIFIER, value, startLine, startCol + 1, this.currentIndent))
|
|
368
|
-
}
|
|
369
|
-
}
|
|
291
|
+
this.tokens.push(new Token(TokenType.COMMENT, value.trim(), startLine, startCol, this.currentIndent))
|
|
370
292
|
}
|
|
371
293
|
|
|
372
294
|
scanBlockComment() {
|
|
373
295
|
const startLine = this.line
|
|
374
296
|
const startCol = this.column
|
|
375
|
-
|
|
376
|
-
|
|
297
|
+
|
|
377
298
|
this.advance()
|
|
378
299
|
this.advance()
|
|
379
|
-
|
|
300
|
+
|
|
301
|
+
let value = ''
|
|
380
302
|
while (!this.isAtEnd()) {
|
|
381
303
|
if (this.peek() === '*' && this.peek(1) === '/') {
|
|
382
304
|
this.advance()
|
|
383
305
|
this.advance()
|
|
384
306
|
break
|
|
385
307
|
}
|
|
386
|
-
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
if (this.options.trackComments) {
|
|
390
|
-
this.tokens.push(new Token(TokenType.BLOCK_COMMENT, comment.trim(), startLine, startCol, this.currentIndent))
|
|
308
|
+
value += this.advance()
|
|
391
309
|
}
|
|
310
|
+
|
|
311
|
+
this.tokens.push(new Token(TokenType.BLOCK_COMMENT, value.trim(), startLine, startCol, this.currentIndent))
|
|
392
312
|
}
|
|
393
313
|
|
|
394
|
-
scanString(
|
|
314
|
+
scanString() {
|
|
395
315
|
const startLine = this.line
|
|
396
316
|
const startCol = this.column
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
this.advance()
|
|
401
|
-
|
|
317
|
+
const quote = this.advance()
|
|
318
|
+
|
|
402
319
|
if (this.peek() === quote && this.peek(1) === quote) {
|
|
403
320
|
this.advance()
|
|
404
321
|
this.advance()
|
|
405
|
-
|
|
322
|
+
return this.scanBlockString(quote, startLine, startCol)
|
|
406
323
|
}
|
|
407
|
-
|
|
324
|
+
|
|
325
|
+
let value = ''
|
|
326
|
+
let escaped = false
|
|
327
|
+
|
|
408
328
|
while (!this.isAtEnd()) {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
this.advance()
|
|
414
|
-
break
|
|
415
|
-
}
|
|
416
|
-
} else {
|
|
417
|
-
if (this.peek() === quote) {
|
|
418
|
-
this.advance()
|
|
419
|
-
break
|
|
420
|
-
}
|
|
421
|
-
if (this.peek() === '\n') {
|
|
422
|
-
this.tokens.push(new Token(TokenType.ERROR, 'Chaîne non terminée', startLine, startCol, this.currentIndent))
|
|
423
|
-
return
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
if (this.peek() === '\\' && !isBlock) {
|
|
428
|
-
this.advance()
|
|
429
|
-
const escaped = this.advance()
|
|
430
|
-
switch (escaped) {
|
|
329
|
+
const char = this.peek()
|
|
330
|
+
|
|
331
|
+
if (escaped) {
|
|
332
|
+
switch (char) {
|
|
431
333
|
case 'n': value += '\n'; break
|
|
432
334
|
case 't': value += '\t'; break
|
|
433
335
|
case 'r': value += '\r'; break
|
|
434
336
|
case '\\': value += '\\'; break
|
|
435
337
|
case "'": value += "'"; break
|
|
436
338
|
case '"': value += '"'; break
|
|
437
|
-
|
|
438
|
-
case 'x':
|
|
439
|
-
let hex = ''
|
|
440
|
-
for (let i = 0; i < 2 && this.isHexDigit(this.peek()); i++) {
|
|
441
|
-
hex += this.advance()
|
|
442
|
-
}
|
|
443
|
-
value += String.fromCharCode(parseInt(hex, 16))
|
|
444
|
-
break
|
|
445
|
-
case 'u':
|
|
446
|
-
let unicode = ''
|
|
447
|
-
if (this.peek() === '{') {
|
|
448
|
-
this.advance()
|
|
449
|
-
while (this.isHexDigit(this.peek())) {
|
|
450
|
-
unicode += this.advance()
|
|
451
|
-
}
|
|
452
|
-
if (this.peek() === '}') this.advance()
|
|
453
|
-
} else {
|
|
454
|
-
for (let i = 0; i < 4 && this.isHexDigit(this.peek()); i++) {
|
|
455
|
-
unicode += this.advance()
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
value += String.fromCodePoint(parseInt(unicode, 16))
|
|
459
|
-
break
|
|
460
|
-
default:
|
|
461
|
-
value += escaped
|
|
339
|
+
default: value += char
|
|
462
340
|
}
|
|
341
|
+
escaped = false
|
|
342
|
+
this.advance()
|
|
343
|
+
} else if (char === '\\') {
|
|
344
|
+
escaped = true
|
|
345
|
+
this.advance()
|
|
346
|
+
} else if (char === quote) {
|
|
347
|
+
this.advance()
|
|
348
|
+
break
|
|
349
|
+
} else if (char === '\n') {
|
|
350
|
+
break
|
|
463
351
|
} else {
|
|
464
352
|
value += this.advance()
|
|
465
353
|
}
|
|
466
354
|
}
|
|
355
|
+
|
|
356
|
+
this.tokens.push(new Token(TokenType.STRING, value, startLine, startCol, this.currentIndent))
|
|
357
|
+
}
|
|
467
358
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
359
|
+
scanBlockString(quote, startLine, startCol) {
|
|
360
|
+
let value = ''
|
|
361
|
+
|
|
362
|
+
while (!this.isAtEnd()) {
|
|
363
|
+
if (this.peek() === quote && this.peek(1) === quote && this.peek(2) === quote) {
|
|
364
|
+
this.advance()
|
|
365
|
+
this.advance()
|
|
366
|
+
this.advance()
|
|
367
|
+
break
|
|
368
|
+
}
|
|
369
|
+
value += this.advance()
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
this.tokens.push(new Token(TokenType.BLOCK_STRING, value, startLine, startCol, this.currentIndent))
|
|
475
373
|
}
|
|
476
374
|
|
|
477
375
|
scanTemplateString() {
|
|
478
376
|
const startLine = this.line
|
|
479
377
|
const startCol = this.column
|
|
480
|
-
let value = ''
|
|
481
|
-
|
|
482
378
|
this.advance()
|
|
483
|
-
|
|
379
|
+
|
|
380
|
+
let value = ''
|
|
381
|
+
|
|
484
382
|
while (!this.isAtEnd() && this.peek() !== '`') {
|
|
485
|
-
if (this.peek() === '\\') {
|
|
383
|
+
if (this.peek() === '\\' && this.peek(1) === '`') {
|
|
486
384
|
this.advance()
|
|
487
385
|
value += this.advance()
|
|
488
386
|
} else {
|
|
489
387
|
value += this.advance()
|
|
490
388
|
}
|
|
491
389
|
}
|
|
492
|
-
|
|
493
|
-
if (this.
|
|
390
|
+
|
|
391
|
+
if (!this.isAtEnd()) {
|
|
494
392
|
this.advance()
|
|
495
393
|
}
|
|
496
|
-
|
|
497
|
-
this.tokens.push(new Token(TokenType.
|
|
394
|
+
|
|
395
|
+
this.tokens.push(new Token(TokenType.STRING, value, startLine, startCol, this.currentIndent))
|
|
498
396
|
}
|
|
499
397
|
|
|
500
398
|
scanNumber() {
|
|
501
399
|
const startLine = this.line
|
|
502
400
|
const startCol = this.column
|
|
503
401
|
let value = ''
|
|
504
|
-
let
|
|
505
|
-
|
|
506
|
-
if (this.peek() === '-') {
|
|
507
|
-
value += this.advance()
|
|
508
|
-
}
|
|
509
|
-
|
|
402
|
+
let tokenType = TokenType.INTEGER
|
|
403
|
+
|
|
510
404
|
if (this.peek() === '0' && (this.peek(1) === 'x' || this.peek(1) === 'X')) {
|
|
511
405
|
value += this.advance()
|
|
512
406
|
value += this.advance()
|
|
513
|
-
while (this.isHexDigit(this.peek())) {
|
|
407
|
+
while (!this.isAtEnd() && this.isHexDigit(this.peek())) {
|
|
514
408
|
value += this.advance()
|
|
515
409
|
}
|
|
516
410
|
this.tokens.push(new Token(TokenType.HEX, value, startLine, startCol, this.currentIndent))
|
|
517
411
|
return
|
|
518
412
|
}
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
this.advance()
|
|
522
|
-
this.advance()
|
|
523
|
-
let binValue = ''
|
|
524
|
-
while (this.peek() === '0' || this.peek() === '1') {
|
|
525
|
-
binValue += this.advance()
|
|
526
|
-
}
|
|
527
|
-
this.tokens.push(new Token(TokenType.INTEGER, parseInt(binValue, 2), startLine, startCol, this.currentIndent))
|
|
528
|
-
return
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
if (this.peek() === '0' && (this.peek(1) === 'o' || this.peek(1) === 'O')) {
|
|
532
|
-
this.advance()
|
|
533
|
-
this.advance()
|
|
534
|
-
let octValue = ''
|
|
535
|
-
while (this.peek() >= '0' && this.peek() <= '7') {
|
|
536
|
-
octValue += this.advance()
|
|
537
|
-
}
|
|
538
|
-
this.tokens.push(new Token(TokenType.INTEGER, parseInt(octValue, 8), startLine, startCol, this.currentIndent))
|
|
539
|
-
return
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
while (this.isDigit(this.peek()) || this.peek() === '_') {
|
|
543
|
-
if (this.peek() !== '_') {
|
|
544
|
-
value += this.advance()
|
|
545
|
-
} else {
|
|
546
|
-
this.advance()
|
|
547
|
-
}
|
|
413
|
+
|
|
414
|
+
while (!this.isAtEnd() && this.isDigit(this.peek())) {
|
|
415
|
+
value += this.advance()
|
|
548
416
|
}
|
|
549
|
-
|
|
417
|
+
|
|
550
418
|
if (this.peek() === '.' && this.isDigit(this.peek(1))) {
|
|
551
|
-
|
|
419
|
+
tokenType = TokenType.FLOAT
|
|
552
420
|
value += this.advance()
|
|
553
|
-
while (this.
|
|
554
|
-
if (this.peek() !== '_') {
|
|
555
|
-
value += this.advance()
|
|
556
|
-
} else {
|
|
557
|
-
this.advance()
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
if (this.peek() === 'e' || this.peek() === 'E') {
|
|
563
|
-
const nextChar = this.peek(1)
|
|
564
|
-
if (this.isDigit(nextChar) || nextChar === '+' || nextChar === '-') {
|
|
565
|
-
type = TokenType.FLOAT
|
|
421
|
+
while (!this.isAtEnd() && this.isDigit(this.peek())) {
|
|
566
422
|
value += this.advance()
|
|
567
|
-
if (this.peek() === '+' || this.peek() === '-') {
|
|
568
|
-
value += this.advance()
|
|
569
|
-
}
|
|
570
|
-
while (this.isDigit(this.peek())) {
|
|
571
|
-
value += this.advance()
|
|
572
|
-
}
|
|
573
423
|
}
|
|
574
424
|
}
|
|
575
|
-
|
|
576
|
-
if (type === TokenType.FLOAT) {
|
|
577
|
-
let numValue = String(parseFloat(value))
|
|
578
|
-
const unit = this.scanCSSUnit()
|
|
579
|
-
if (unit) numValue += unit
|
|
580
|
-
this.tokens.push(new Token(type, numValue, startLine, startCol, this.currentIndent))
|
|
581
|
-
} else {
|
|
582
|
-
let numValue = String(parseInt(value, 10))
|
|
583
|
-
const unit = this.scanCSSUnit()
|
|
584
|
-
if (unit) numValue += unit
|
|
585
|
-
this.tokens.push(new Token(type, numValue, startLine, startCol, this.currentIndent))
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
scanCSSUnit() {
|
|
590
|
-
const units = ['px', 'em', 'rem', 'vh', 'vw', 'vmin', 'vmax', '%', 'fr', 's', 'ms', 'deg', 'rad', 'turn', 'ch', 'ex', 'cm', 'mm', 'in', 'pt', 'pc', 'cqw', 'cqh']
|
|
591
425
|
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
matches = false
|
|
598
|
-
break
|
|
599
|
-
}
|
|
426
|
+
if (this.peek() === 'e' || this.peek() === 'E') {
|
|
427
|
+
tokenType = TokenType.FLOAT
|
|
428
|
+
value += this.advance()
|
|
429
|
+
if (this.peek() === '+' || this.peek() === '-') {
|
|
430
|
+
value += this.advance()
|
|
600
431
|
}
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
if (!afterUnit || !this.isAlpha(afterUnit)) {
|
|
604
|
-
let result = ''
|
|
605
|
-
for (let i = 0; i < unit.length; i++) {
|
|
606
|
-
result += this.advance()
|
|
607
|
-
}
|
|
608
|
-
return result
|
|
609
|
-
}
|
|
432
|
+
while (!this.isAtEnd() && this.isDigit(this.peek())) {
|
|
433
|
+
value += this.advance()
|
|
610
434
|
}
|
|
611
435
|
}
|
|
612
|
-
|
|
436
|
+
|
|
437
|
+
const numValue = tokenType === TokenType.INTEGER ? parseInt(value, 10) : parseFloat(value)
|
|
438
|
+
this.tokens.push(new Token(tokenType, numValue, startLine, startCol, this.currentIndent))
|
|
613
439
|
}
|
|
614
440
|
|
|
615
441
|
scanIdentifier() {
|
|
616
442
|
const startLine = this.line
|
|
617
443
|
const startCol = this.column
|
|
618
444
|
let value = ''
|
|
619
|
-
|
|
620
|
-
|
|
445
|
+
|
|
446
|
+
if (this.peek() === '$') {
|
|
447
|
+
value += this.advance()
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
while (!this.isAtEnd() && (this.isAlphaNumeric(this.peek()) || this.peek() === '_' || this.peek() === '-' && this.isAlpha(this.peek(1)))) {
|
|
621
451
|
value += this.advance()
|
|
622
452
|
}
|
|
623
453
|
|
|
624
454
|
let keepLooking = true
|
|
625
|
-
while (keepLooking && this.
|
|
455
|
+
while (keepLooking && !this.isAtEnd()) {
|
|
626
456
|
const savedPos = this.pos
|
|
627
457
|
const savedLine = this.line
|
|
628
458
|
const savedCol = this.column
|
|
629
459
|
|
|
630
|
-
this.
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
460
|
+
if (this.peek() === ' ') {
|
|
461
|
+
let spaces = ''
|
|
462
|
+
while (this.peek() === ' ') {
|
|
463
|
+
spaces += this.advance()
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
if (this.isAlpha(this.peek()) || this.peek() === "'" || this.peek() === '-') {
|
|
467
|
+
let nextWord = ''
|
|
468
|
+
while (!this.isAtEnd() && (this.isAlphaNumeric(this.peek()) || this.peek() === '_' || this.peek() === "'" || this.peek() === '-' && this.isAlpha(this.peek(1)))) {
|
|
469
|
+
nextWord += this.advance()
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
const compound = value + ' ' + nextWord
|
|
473
|
+
if (this.isCompoundKeyword(compound) || this.couldBeCompoundStart(compound)) {
|
|
474
|
+
value = compound
|
|
475
|
+
} else {
|
|
476
|
+
this.pos = savedPos
|
|
477
|
+
this.line = savedLine
|
|
478
|
+
this.column = savedCol
|
|
479
|
+
keepLooking = false
|
|
480
|
+
}
|
|
641
481
|
} else {
|
|
642
482
|
this.pos = savedPos
|
|
643
483
|
this.line = savedLine
|
|
@@ -664,12 +504,7 @@ class EtherLexer {
|
|
|
664
504
|
|
|
665
505
|
couldBeCompoundStart(partial) {
|
|
666
506
|
const normalized = this.normalizeAccents(partial)
|
|
667
|
-
const compounds =
|
|
668
|
-
'retour a la ligne', 'a la soumission', 'a la reinitialisation',
|
|
669
|
-
'inferieur ou egal', 'superieur ou egal',
|
|
670
|
-
'gauche a droite', 'droite a gauche',
|
|
671
|
-
'mettre a jour', 'case a cocher'
|
|
672
|
-
]
|
|
507
|
+
const compounds = this.getCompoundKeywords()
|
|
673
508
|
return compounds.some(c => c.startsWith(normalized + ' '))
|
|
674
509
|
}
|
|
675
510
|
|
|
@@ -685,9 +520,12 @@ class EtherLexer {
|
|
|
685
520
|
return str.toLowerCase().split('').map(c => accentsMap[c] || c).join('')
|
|
686
521
|
}
|
|
687
522
|
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
523
|
+
getCompoundKeywords() {
|
|
524
|
+
if (this.compoundKeywordsCache) {
|
|
525
|
+
return this.compoundKeywordsCache
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
this.compoundKeywordsCache = [
|
|
691
529
|
'en ligne', 'hors ligne', 'au survol', 'au clic', 'au focus',
|
|
692
530
|
'au double clic', 'au changement', 'a la soumission',
|
|
693
531
|
'retour a la ligne', 'lecture seule', 'zone texte',
|
|
@@ -727,9 +565,173 @@ class EtherLexer {
|
|
|
727
565
|
'couleur bordure', 'style bordure', 'largeur bordure',
|
|
728
566
|
'espacement lettres', 'espacement mots',
|
|
729
567
|
'espace blanc', 'debordement texte',
|
|
730
|
-
'flou fond', 'filtre fond'
|
|
568
|
+
'flou fond', 'filtre fond',
|
|
569
|
+
|
|
570
|
+
'obtenir type', 'definir type',
|
|
571
|
+
'est tableau', 'est booleen', 'est entier', 'est chaine',
|
|
572
|
+
'est nul', 'est flottant', 'est numerique', 'est objet',
|
|
573
|
+
'est ressource', 'est scalaire', 'est iterable', 'est comptable',
|
|
574
|
+
'est appelable', 'est vide',
|
|
575
|
+
'valeur entier', 'valeur flottant', 'valeur chaine', 'valeur booleen',
|
|
576
|
+
'afficher formate', 'formater chaine',
|
|
577
|
+
'afficher variable', 'exporter variable',
|
|
578
|
+
'imprimer lisible', 'deboguer zval',
|
|
579
|
+
'somme tableau', 'filtrer tableau', 'mapper tableau',
|
|
580
|
+
'fusionner tableaux', 'reduire tableau',
|
|
581
|
+
'trier tableau', 'inverser tableau', 'melanger tableau',
|
|
582
|
+
'premier tableau', 'dernier tableau',
|
|
583
|
+
'cles tableau', 'valeurs tableau',
|
|
584
|
+
'rechercher tableau', 'existe cle', 'existe tableau',
|
|
585
|
+
'couper espaces', 'couper gauche', 'couper droite',
|
|
586
|
+
'en majuscules', 'en minuscules',
|
|
587
|
+
'premiere majuscule', 'majuscules mots',
|
|
588
|
+
'longueur chaine', 'sous chaine',
|
|
589
|
+
'position chaine', 'remplacer chaine',
|
|
590
|
+
'exploser chaine', 'imploser tableau',
|
|
591
|
+
'lire fichier', 'ecrire fichier',
|
|
592
|
+
'fichier existe', 'supprimer fichier',
|
|
593
|
+
'creer dossier', 'lire dossier', 'supprimer dossier',
|
|
594
|
+
'encoder json', 'decoder json',
|
|
595
|
+
'encoder base64', 'decoder base64',
|
|
596
|
+
'encoder url', 'decoder url',
|
|
597
|
+
'hacher md5', 'hacher sha1', 'hacher sha256',
|
|
598
|
+
'hacher mot de passe', 'verifier mot de passe',
|
|
599
|
+
'mot de passe',
|
|
600
|
+
'demarrer session', 'detruire session',
|
|
601
|
+
'sinon si',
|
|
602
|
+
'nouvelle instance', 'nouveau datetime',
|
|
603
|
+
'classe abstraite', 'classe finale',
|
|
604
|
+
'methode abstraite', 'methode finale',
|
|
605
|
+
'propriete privee', 'propriete protegee', 'propriete publique',
|
|
606
|
+
'lecture seule',
|
|
607
|
+
|
|
608
|
+
'creer base de donnees', 'creer table', 'creer vue',
|
|
609
|
+
'creer index', 'creer index unique',
|
|
610
|
+
'creer schema', 'creer sequence', 'creer type', 'creer domaine',
|
|
611
|
+
'creer fonction', 'creer procedure', 'creer declencheur',
|
|
612
|
+
'creer ou remplacer', 'creer role',
|
|
613
|
+
'si n\'existe pas', 'si nexiste pas',
|
|
614
|
+
'modifier table', 'modifier colonne', 'modifier base de donnees',
|
|
615
|
+
'modifier index', 'modifier sequence', 'modifier vue',
|
|
616
|
+
'ajouter colonne', 'supprimer colonne',
|
|
617
|
+
'renommer en', 'renommer colonne', 'modifier type',
|
|
618
|
+
'definir defaut', 'supprimer defaut',
|
|
619
|
+
'supprimer base de donnees', 'supprimer table', 'supprimer vue',
|
|
620
|
+
'supprimer index', 'supprimer schema', 'supprimer sequence',
|
|
621
|
+
'supprimer fonction', 'supprimer procedure', 'supprimer declencheur',
|
|
622
|
+
'supprimer role', 'supprimer contrainte',
|
|
623
|
+
'cle primaire', 'cle etrangere', 'non nul', 'par defaut',
|
|
624
|
+
'auto increment', 'unique contrainte',
|
|
625
|
+
'verifier contrainte', 'references table',
|
|
626
|
+
'sur suppression', 'sur mise a jour',
|
|
627
|
+
'cascade suppression', 'cascade mise a jour',
|
|
628
|
+
'definir null', 'sans action',
|
|
629
|
+
'inserer dans', 'inserer valeurs',
|
|
630
|
+
'mettre a jour', 'definir valeur',
|
|
631
|
+
'supprimer de', 'supprimer ou',
|
|
632
|
+
'selectionner depuis', 'selectionner tout',
|
|
633
|
+
'selectionner distinct', 'selectionner comme',
|
|
634
|
+
'depuis table', 'ou condition', 'et condition',
|
|
635
|
+
'grouper par', 'ordonner par', 'limiter a',
|
|
636
|
+
'decaler de', 'avoir condition',
|
|
637
|
+
'jointure gauche', 'jointure droite',
|
|
638
|
+
'jointure interne', 'jointure externe',
|
|
639
|
+
'jointure croisee', 'jointure naturelle',
|
|
640
|
+
'jointure complete',
|
|
641
|
+
'union tout', 'sauf tout', 'intersection tout',
|
|
642
|
+
'compter tout', 'somme de', 'moyenne de',
|
|
643
|
+
'maximum de', 'minimum de',
|
|
644
|
+
'comme motif', 'similaire a', 'correspond a regex',
|
|
645
|
+
'correspond regex insensible',
|
|
646
|
+
'ne correspond pas regex', 'ne correspond pas regex insensible',
|
|
647
|
+
'est null', 'n\'est pas null', 'nest pas null',
|
|
648
|
+
'est distinct de', 'n\'est pas distinct de', 'nest pas distinct de',
|
|
649
|
+
'entre et', 'pas entre',
|
|
650
|
+
'tout de', 'quelconque de', 'aucun de',
|
|
651
|
+
'dans liste', 'pas dans liste',
|
|
652
|
+
'existe sous requete', 'n\'existe pas sous requete',
|
|
653
|
+
'debut transaction', 'valider transaction', 'annuler transaction',
|
|
654
|
+
'point de sauvegarde', 'revenir a', 'liberer sauvegarde',
|
|
655
|
+
'definir transaction', 'lecture seule', 'lecture ecriture',
|
|
656
|
+
'niveau isolation', 'lecture non validee',
|
|
657
|
+
'lecture validee', 'lecture repetable', 'serialisable',
|
|
658
|
+
'verrouiller table', 'deverrouiller tables',
|
|
659
|
+
'verrouiller ligne', 'pour mise a jour',
|
|
660
|
+
'pour partage', 'sauter verrouille', 'sans attendre',
|
|
661
|
+
'accorder privileges', 'revoquer privileges',
|
|
662
|
+
'accorder tout', 'revoquer tout',
|
|
663
|
+
'avec option grant', 'option admin',
|
|
664
|
+
'creer utilisateur', 'supprimer utilisateur',
|
|
665
|
+
'modifier utilisateur', 'definir mot de passe',
|
|
666
|
+
'expliquer analyser', 'expliquer verbose',
|
|
667
|
+
'commentaire sur', 'commentaire ligne', 'commentaire bloc',
|
|
668
|
+
'tableau contient', 'contenu dans tableau',
|
|
669
|
+
'chevauchement tableau', 'longueur tableau',
|
|
670
|
+
'ajouter tableau', 'prefixer tableau',
|
|
671
|
+
'concatener tableaux', 'supprimer tableau',
|
|
672
|
+
'remplacer tableau', 'position tableau', 'positions tableau',
|
|
673
|
+
'vers chaine tableau', 'depuis chaine tableau',
|
|
674
|
+
'denombrer tableau',
|
|
675
|
+
'remplacer regex', 'correspondance regex', 'correspondances regex',
|
|
676
|
+
'diviser regex', 'tableau regex',
|
|
677
|
+
'extraire json', 'extraire texte json',
|
|
678
|
+
'contient json', 'existe json',
|
|
679
|
+
'type json', 'tableau json', 'objet json',
|
|
680
|
+
'cle json', 'valeur json',
|
|
681
|
+
'ensemble json', 'supprimer cle json',
|
|
682
|
+
'definir valeur json', 'inserer json',
|
|
683
|
+
'concatener json', 'chaque json',
|
|
684
|
+
'elements json', 'cles json',
|
|
685
|
+
'vers json', 'depuis json',
|
|
686
|
+
'maintenant timestamp', 'date courante', 'heure courante',
|
|
687
|
+
'timestamp courant', 'extraire date',
|
|
688
|
+
'partie date', 'tronquer date',
|
|
689
|
+
'age entre', 'intervalle temps',
|
|
690
|
+
'debut mois', 'fin mois',
|
|
691
|
+
'ajouter intervalle', 'soustraire intervalle',
|
|
692
|
+
'fuseau horaire', 'convertir fuseau',
|
|
693
|
+
'generer serie', 'generer dates',
|
|
694
|
+
'valeur suivante', 'valeur courante',
|
|
695
|
+
'definir valeur sequence', 'redemarrer sequence',
|
|
696
|
+
'fenetre sur', 'partitionner par',
|
|
697
|
+
'lignes precedentes', 'lignes suivantes',
|
|
698
|
+
'premiere valeur', 'derniere valeur',
|
|
699
|
+
'nieme valeur', 'rang dense', 'numero ligne',
|
|
700
|
+
'pourcentage rang', 'distribution cumulee',
|
|
701
|
+
'ntile groupe', 'valeur precedente', 'valeur suivante fenetre',
|
|
702
|
+
'somme cumulative', 'moyenne mobile',
|
|
703
|
+
'table temporaire', 'table non journalisee',
|
|
704
|
+
'sur conflit', 'ne rien faire', 'mettre a jour conflit',
|
|
705
|
+
'retourner tout', 'retourner insere',
|
|
706
|
+
'avec requete', 'requete recursive',
|
|
707
|
+
'table virtuelle', 'table materialisee',
|
|
708
|
+
'rafraichir vue', 'rafraichir concurrent',
|
|
709
|
+
'activer declencheur', 'desactiver declencheur',
|
|
710
|
+
'avant insertion', 'apres insertion',
|
|
711
|
+
'avant mise a jour', 'apres mise a jour',
|
|
712
|
+
'avant suppression', 'apres suppression',
|
|
713
|
+
'pour chaque ligne', 'pour chaque instruction',
|
|
714
|
+
'quand condition', 'executer procedure',
|
|
715
|
+
'declarer variable', 'definir variable',
|
|
716
|
+
'debut bloc', 'fin bloc',
|
|
717
|
+
'si condition', 'sinon si condition', 'sinon condition',
|
|
718
|
+
'boucle tant que', 'boucle pour', 'sortir boucle',
|
|
719
|
+
'continuer boucle', 'retourner valeur',
|
|
720
|
+
'lever exception', 'capturer exception',
|
|
721
|
+
'bloc exception', 'quand autres',
|
|
722
|
+
'afficher message', 'afficher avertissement', 'afficher erreur',
|
|
723
|
+
'curseur pour', 'ouvrir curseur', 'fermer curseur',
|
|
724
|
+
'recuperer suivant', 'recuperer precedent',
|
|
725
|
+
'recuperer premier', 'recuperer dernier',
|
|
726
|
+
'ligne trouvee', 'ligne non trouvee'
|
|
731
727
|
]
|
|
732
|
-
|
|
728
|
+
|
|
729
|
+
return this.compoundKeywordsCache
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
isCompoundKeyword(phrase) {
|
|
733
|
+
const normalized = this.normalizeAccents(phrase)
|
|
734
|
+
return this.getCompoundKeywords().includes(normalized)
|
|
733
735
|
}
|
|
734
736
|
|
|
735
737
|
scanOperator() {
|
|
@@ -801,19 +803,11 @@ class EtherLexer {
|
|
|
801
803
|
|
|
802
804
|
case '-':
|
|
803
805
|
if (this.match('-')) {
|
|
804
|
-
|
|
805
|
-
let varName = '--'
|
|
806
|
-
while (this.isAlphaNumeric(this.peek()) || this.peek() === '-' || this.peek() === '_') {
|
|
807
|
-
varName += this.advance()
|
|
808
|
-
}
|
|
809
|
-
this.tokens.push(new Token(TokenType.IDENTIFIER, varName, startLine, startCol, this.currentIndent))
|
|
810
|
-
} else {
|
|
811
|
-
this.tokens.push(new Token(TokenType.MINUS, '--', startLine, startCol, this.currentIndent))
|
|
812
|
-
}
|
|
813
|
-
} else if (this.match('>')) {
|
|
814
|
-
this.tokens.push(new Token(TokenType.ARROW, '->', startLine, startCol, this.currentIndent))
|
|
806
|
+
this.tokens.push(new Token(TokenType.MINUS, '--', startLine, startCol, this.currentIndent))
|
|
815
807
|
} else if (this.match('=')) {
|
|
816
808
|
this.tokens.push(new Token(TokenType.MINUS, '-=', startLine, startCol, this.currentIndent))
|
|
809
|
+
} else if (this.match('>')) {
|
|
810
|
+
this.tokens.push(new Token(TokenType.ARROW, '->', startLine, startCol, this.currentIndent))
|
|
817
811
|
} else {
|
|
818
812
|
this.tokens.push(new Token(TokenType.MINUS, '-', startLine, startCol, this.currentIndent))
|
|
819
813
|
}
|
|
@@ -834,10 +828,10 @@ class EtherLexer {
|
|
|
834
828
|
break
|
|
835
829
|
|
|
836
830
|
case '/':
|
|
837
|
-
if (this.match('
|
|
838
|
-
this.tokens.push(new Token(TokenType.SLASH, '/=', startLine, startCol, this.currentIndent))
|
|
839
|
-
} else if (this.match('/')) {
|
|
831
|
+
if (this.match('/')) {
|
|
840
832
|
this.tokens.push(new Token(TokenType.DOUBLE_SLASH, '//', startLine, startCol, this.currentIndent))
|
|
833
|
+
} else if (this.match('=')) {
|
|
834
|
+
this.tokens.push(new Token(TokenType.SLASH, '/=', startLine, startCol, this.currentIndent))
|
|
841
835
|
} else {
|
|
842
836
|
this.tokens.push(new Token(TokenType.SLASH, '/', startLine, startCol, this.currentIndent))
|
|
843
837
|
}
|
|
@@ -859,7 +853,13 @@ class EtherLexer {
|
|
|
859
853
|
this.tokens.push(new Token(TokenType.LTE, '<=', startLine, startCol, this.currentIndent))
|
|
860
854
|
}
|
|
861
855
|
} else if (this.match('<')) {
|
|
862
|
-
this.
|
|
856
|
+
if (this.match('=')) {
|
|
857
|
+
this.tokens.push(new Token(TokenType.LT, '<<=', startLine, startCol, this.currentIndent))
|
|
858
|
+
} else {
|
|
859
|
+
this.tokens.push(new Token(TokenType.LT, '<<', startLine, startCol, this.currentIndent))
|
|
860
|
+
}
|
|
861
|
+
} else if (this.match('>')) {
|
|
862
|
+
this.tokens.push(new Token(TokenType.NOT_EQUALS, '<>', startLine, startCol, this.currentIndent))
|
|
863
863
|
} else {
|
|
864
864
|
this.tokens.push(new Token(TokenType.LT, '<', startLine, startCol, this.currentIndent))
|
|
865
865
|
}
|
|
@@ -869,8 +869,8 @@ class EtherLexer {
|
|
|
869
869
|
if (this.match('=')) {
|
|
870
870
|
this.tokens.push(new Token(TokenType.GTE, '>=', startLine, startCol, this.currentIndent))
|
|
871
871
|
} else if (this.match('>')) {
|
|
872
|
-
if (this.match('
|
|
873
|
-
this.tokens.push(new Token(TokenType.GT, '
|
|
872
|
+
if (this.match('=')) {
|
|
873
|
+
this.tokens.push(new Token(TokenType.GT, '>>=', startLine, startCol, this.currentIndent))
|
|
874
874
|
} else {
|
|
875
875
|
this.tokens.push(new Token(TokenType.GT, '>>', startLine, startCol, this.currentIndent))
|
|
876
876
|
}
|
|
@@ -894,8 +894,6 @@ class EtherLexer {
|
|
|
894
894
|
this.tokens.push(new Token(TokenType.DOUBLE_PIPE, '||', startLine, startCol, this.currentIndent))
|
|
895
895
|
} else if (this.match('=')) {
|
|
896
896
|
this.tokens.push(new Token(TokenType.PIPE, '|=', startLine, startCol, this.currentIndent))
|
|
897
|
-
} else if (this.match('>')) {
|
|
898
|
-
this.tokens.push(new Token(TokenType.PIPE, '|>', startLine, startCol, this.currentIndent))
|
|
899
897
|
} else {
|
|
900
898
|
this.tokens.push(new Token(TokenType.PIPE, '|', startLine, startCol, this.currentIndent))
|
|
901
899
|
}
|
|
@@ -922,6 +920,8 @@ class EtherLexer {
|
|
|
922
920
|
}
|
|
923
921
|
} else if (this.match('.')) {
|
|
924
922
|
this.tokens.push(new Token(TokenType.QUESTION, '?.', startLine, startCol, this.currentIndent))
|
|
923
|
+
} else if (this.match('-') && this.match('>')) {
|
|
924
|
+
this.tokens.push(new Token(TokenType.ARROW, '?->', startLine, startCol, this.currentIndent))
|
|
925
925
|
} else {
|
|
926
926
|
this.tokens.push(new Token(TokenType.QUESTION, '?', startLine, startCol, this.currentIndent))
|
|
927
927
|
}
|
|
@@ -972,6 +972,30 @@ class EtherLexer {
|
|
|
972
972
|
}
|
|
973
973
|
}
|
|
974
974
|
|
|
975
|
+
isDigit(char) {
|
|
976
|
+
return char >= '0' && char <= '9'
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
isHexDigit(char) {
|
|
980
|
+
return this.isDigit(char) || (char >= 'a' && char <= 'f') || (char >= 'A' && char <= 'F')
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
isAlpha(char) {
|
|
984
|
+
return (char >= 'a' && char <= 'z') ||
|
|
985
|
+
(char >= 'A' && char <= 'Z') ||
|
|
986
|
+
char === '_' ||
|
|
987
|
+
char === '$' ||
|
|
988
|
+
char.charCodeAt(0) > 127
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
isAlphaNumeric(char) {
|
|
992
|
+
return this.isAlpha(char) || this.isDigit(char)
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
isOperator(char) {
|
|
996
|
+
return ':=!,.<>+-*/%&|^~?@#\\()[]{};\n\r\t '.indexOf(char) !== -1
|
|
997
|
+
}
|
|
998
|
+
|
|
975
999
|
static tokenize(source, options = {}) {
|
|
976
1000
|
const lexer = new EtherLexer(source, options)
|
|
977
1001
|
return lexer.tokenize()
|