Skip to content

Commit e79a122

Browse files
committed
fix brace tokoenizer bugs
1 parent 2f78a69 commit e79a122

File tree

8 files changed

+251
-108
lines changed

8 files changed

+251
-108
lines changed

src/message/tokenizer.ts

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
createPosition,
1111
Position
1212
} from './location'
13+
import { isUnDef } from '../utils'
1314

1415
export const enum TokenTypes {
1516
Text, // 0
@@ -26,6 +27,7 @@ export const enum TokenTypes {
2627
LinkedModifier,
2728
ParenLeft,
2829
ParenRight,
30+
InvalidPlace,
2931
EOF
3032
}
3133

@@ -46,13 +48,13 @@ const EOF = undefined
4648

4749
export type Token = {
4850
type: TokenTypes
49-
value?: string | number
51+
value?: string
5052
loc?: SourceLocation
5153
}
5254

5355
export type TokenizeContext = {
5456
currentType: TokenTypes
55-
currentValue: string | number | undefined | null // TODO: if dont' use, should be removed
57+
currentValue: string | undefined | null // TODO: if dont' use, should be removed
5658
currentToken: Token | null
5759
offset: number
5860
startLoc: Position
@@ -62,6 +64,7 @@ export type TokenizeContext = {
6264
lastOffset: number
6365
lastStartLoc: Position
6466
lastEndLoc: Position
67+
braceNest: number
6568
}
6669

6770
export type Tokenizer = Readonly<{
@@ -91,24 +94,29 @@ export function createTokenizer(source: string): Tokenizer {
9194
lastToken: null,
9295
lastOffset: _initOffset,
9396
lastStartLoc: _initLoc,
94-
lastEndLoc: _initLoc
97+
lastEndLoc: _initLoc,
98+
braceNest: 0
9599
}
96100

97101
const context = (): TokenizeContext => _context
98102

99103
const getToken = (
100104
context: TokenizeContext,
101105
type: TokenTypes,
102-
value?: string | number
106+
value?: string
103107
): Token => {
104108
context.endLoc = currentPosition()
105109
context.currentType = type
106110
context.currentValue = value
107-
return {
111+
const token = {
108112
type,
109-
value,
110113
loc: createLocation(context.startLoc, context.endLoc)
114+
} as Token
115+
116+
if (!isUnDef(value)) {
117+
token.value = value
111118
}
119+
return token
112120
}
113121

114122
const peekSpaces = (scnr: Scanner): string => {
@@ -145,7 +153,7 @@ export function createTokenizer(source: string): Tokenizer {
145153
return cc >= 48 && cc <= 57 // 0-9
146154
}
147155

148-
const isNamedIdentifier = (
156+
const isNamedIdentifierStart = (
149157
scnr: Scanner,
150158
context: TokenizeContext
151159
): boolean => {
@@ -159,7 +167,7 @@ export function createTokenizer(source: string): Tokenizer {
159167
return ret
160168
}
161169

162-
const isListIdentifier = (
170+
const isListIdentifierStart = (
163171
scnr: Scanner,
164172
context: TokenizeContext
165173
): boolean => {
@@ -351,11 +359,10 @@ export function createTokenizer(source: string): Tokenizer {
351359
while ((ch = takeIdentifierChar(scnr))) {
352360
name += ch
353361
}
354-
skipSpaces(scnr)
355362
return name
356363
}
357364

358-
const readListIdentifier = (scnr: Scanner): number => {
365+
const readListIdentifier = (scnr: Scanner): string => {
359366
skipSpaces(scnr)
360367
let value = ''
361368
if (scnr.currentChar() === '-') {
@@ -364,8 +371,18 @@ export function createTokenizer(source: string): Tokenizer {
364371
} else {
365372
value += getDigits(scnr)
366373
}
374+
return value
375+
}
376+
377+
const readInvalidIdentifier = (scnr: Scanner): string => {
367378
skipSpaces(scnr)
368-
return parseInt(value, 10)
379+
let ch: string | undefined | null = ''
380+
let identifiers = ''
381+
const closure = (ch: string) => (ch !== TokenChars.BraceLeft && ch !== TokenChars.BraceRight)
382+
while ((ch = takeChar(scnr, closure))) {
383+
identifiers += ch
384+
}
385+
return identifiers
369386
}
370387

371388
const readLinkedModifierArg = (scnr: Scanner): string => {
@@ -428,10 +445,14 @@ export function createTokenizer(source: string): Tokenizer {
428445
case TokenChars.BraceLeft:
429446
scnr.next()
430447
token = getToken(context, TokenTypes.BraceLeft, TokenChars.BraceLeft)
448+
skipSpaces(scnr)
449+
context.braceNest++
431450
break
432451
case TokenChars.BraceRight:
433452
scnr.next()
434453
token = getToken(context, TokenTypes.BraceRight, TokenChars.BraceRight)
454+
context.braceNest--
455+
context.braceNest > 0 && skipSpaces(scnr)
435456
break
436457
case TokenChars.LinkedAlias:
437458
scnr.next()
@@ -466,14 +487,30 @@ export function createTokenizer(source: string): Tokenizer {
466487
token = getToken(context, TokenTypes.Modulo, TokenChars.Modulo)
467488
break
468489
default:
490+
let validNamedIdentifier = true
491+
let validListIdentifier = true
469492
if (isPluralStart(scnr)) {
470493
token = getToken(context, TokenTypes.Pipe, readPlural(scnr))
494+
context.braceNest = 0 // reset
471495
} else if (isTextStart(scnr, context)) {
472496
token = getToken(context, TokenTypes.Text, readText(scnr))
473-
} else if (isNamedIdentifier(scnr, context)) {
497+
} else if (
498+
(validNamedIdentifier = isNamedIdentifierStart(scnr, context))
499+
) {
474500
token = getToken(context, TokenTypes.Named, readNamedIdentifier(scnr))
475-
} else if (isListIdentifier(scnr, context)) {
501+
skipSpaces(scnr)
502+
} else if (
503+
(validListIdentifier = isListIdentifierStart(scnr, context))
504+
) {
476505
token = getToken(context, TokenTypes.List, readListIdentifier(scnr))
506+
skipSpaces(scnr)
507+
// } else if (!validNamedIdentifier && !validListIdentifier) {
508+
// token = getToken(
509+
// context,
510+
// TokenTypes.InvalidPlace,
511+
// readInvalidIdentifier(scnr)
512+
// )
513+
// skipSpaces(scnr)
477514
} else if (isLinkedModifier(scnr, context)) {
478515
token = getToken(
479516
context,

0 commit comments

Comments
 (0)