124 lines
2.8 KiB
TypeScript
124 lines
2.8 KiB
TypeScript
|
|
import isString from "lodash/isString"
|
||
|
|
import has from "lodash/has"
|
||
|
|
import isUndefined from "lodash/isUndefined"
|
||
|
|
import { Lexer } from "./lexer_public"
|
||
|
|
import { augmentTokenTypes, tokenStructuredMatcher } from "./tokens"
|
||
|
|
import { IToken, ITokenConfig, TokenType } from "@chevrotain/types"
|
||
|
|
|
||
|
|
export function tokenLabel(tokType: TokenType): string {
|
||
|
|
if (hasTokenLabel(tokType)) {
|
||
|
|
return tokType.LABEL
|
||
|
|
} else {
|
||
|
|
return tokType.name
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export function tokenName(tokType: TokenType): string {
|
||
|
|
return tokType.name
|
||
|
|
}
|
||
|
|
|
||
|
|
export function hasTokenLabel(
|
||
|
|
obj: TokenType
|
||
|
|
): obj is TokenType & Pick<Required<TokenType>, "LABEL"> {
|
||
|
|
return isString(obj.LABEL) && obj.LABEL !== ""
|
||
|
|
}
|
||
|
|
|
||
|
|
const PARENT = "parent"
|
||
|
|
const CATEGORIES = "categories"
|
||
|
|
const LABEL = "label"
|
||
|
|
const GROUP = "group"
|
||
|
|
const PUSH_MODE = "push_mode"
|
||
|
|
const POP_MODE = "pop_mode"
|
||
|
|
const LONGER_ALT = "longer_alt"
|
||
|
|
const LINE_BREAKS = "line_breaks"
|
||
|
|
const START_CHARS_HINT = "start_chars_hint"
|
||
|
|
|
||
|
|
export function createToken(config: ITokenConfig): TokenType {
|
||
|
|
return createTokenInternal(config)
|
||
|
|
}
|
||
|
|
|
||
|
|
function createTokenInternal(config: ITokenConfig): TokenType {
|
||
|
|
const pattern = config.pattern
|
||
|
|
|
||
|
|
const tokenType: TokenType = <any>{}
|
||
|
|
tokenType.name = config.name
|
||
|
|
|
||
|
|
if (!isUndefined(pattern)) {
|
||
|
|
tokenType.PATTERN = pattern
|
||
|
|
}
|
||
|
|
|
||
|
|
if (has(config, PARENT)) {
|
||
|
|
throw (
|
||
|
|
"The parent property is no longer supported.\n" +
|
||
|
|
"See: https://github.com/chevrotain/chevrotain/issues/564#issuecomment-349062346 for details."
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
if (has(config, CATEGORIES)) {
|
||
|
|
// casting to ANY as this will be fixed inside `augmentTokenTypes``
|
||
|
|
tokenType.CATEGORIES = <any>config[CATEGORIES]
|
||
|
|
}
|
||
|
|
|
||
|
|
augmentTokenTypes([tokenType])
|
||
|
|
|
||
|
|
if (has(config, LABEL)) {
|
||
|
|
tokenType.LABEL = config[LABEL]
|
||
|
|
}
|
||
|
|
|
||
|
|
if (has(config, GROUP)) {
|
||
|
|
tokenType.GROUP = config[GROUP]
|
||
|
|
}
|
||
|
|
|
||
|
|
if (has(config, POP_MODE)) {
|
||
|
|
tokenType.POP_MODE = config[POP_MODE]
|
||
|
|
}
|
||
|
|
|
||
|
|
if (has(config, PUSH_MODE)) {
|
||
|
|
tokenType.PUSH_MODE = config[PUSH_MODE]
|
||
|
|
}
|
||
|
|
|
||
|
|
if (has(config, LONGER_ALT)) {
|
||
|
|
tokenType.LONGER_ALT = config[LONGER_ALT]
|
||
|
|
}
|
||
|
|
|
||
|
|
if (has(config, LINE_BREAKS)) {
|
||
|
|
tokenType.LINE_BREAKS = config[LINE_BREAKS]
|
||
|
|
}
|
||
|
|
|
||
|
|
if (has(config, START_CHARS_HINT)) {
|
||
|
|
tokenType.START_CHARS_HINT = config[START_CHARS_HINT]
|
||
|
|
}
|
||
|
|
|
||
|
|
return tokenType
|
||
|
|
}
|
||
|
|
|
||
|
|
export const EOF = createToken({ name: "EOF", pattern: Lexer.NA })
|
||
|
|
augmentTokenTypes([EOF])
|
||
|
|
|
||
|
|
export function createTokenInstance(
|
||
|
|
tokType: TokenType,
|
||
|
|
image: string,
|
||
|
|
startOffset: number,
|
||
|
|
endOffset: number,
|
||
|
|
startLine: number,
|
||
|
|
endLine: number,
|
||
|
|
startColumn: number,
|
||
|
|
endColumn: number
|
||
|
|
): IToken {
|
||
|
|
return {
|
||
|
|
image,
|
||
|
|
startOffset,
|
||
|
|
endOffset,
|
||
|
|
startLine,
|
||
|
|
endLine,
|
||
|
|
startColumn,
|
||
|
|
endColumn,
|
||
|
|
tokenTypeIdx: (<any>tokType).tokenTypeIdx,
|
||
|
|
tokenType: tokType
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export function tokenMatcher(token: IToken, tokType: TokenType): boolean {
|
||
|
|
return tokenStructuredMatcher(token, tokType)
|
||
|
|
}
|