/
makePayloadPattern.ts
54 lines (51 loc) · 1.62 KB
/
makePayloadPattern.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import { ICustomPattern, IToken } from "chevrotain";
import { strict as assert } from "assert";
// You can use custom payloads to store the full text and other information in
// the token. This allows a CST visitor to operate on the full document. See
// http://sap.github.io/chevrotain/docs/guide/custom_token_patterns.html#custom-payloads
export interface PayloadQuery {
text: string;
offset: number;
tokens: IToken[];
groups: {
[groupName: string]: IToken[];
};
result: RegExpExecArray;
}
// Creates a CustomPattern with the given RegExp and getPayload callback
// function, which is called whenever the token is encountered by the lexer.
// It should return the payload for the token in the given circumstance.
export function makePayloadPattern<PayloadType>(
pattern: RegExp,
getPayload: (query: PayloadQuery) => PayloadType
): ICustomPattern {
assert(
pattern.sticky,
"Custom pattern MUST be sticky (e.g. `y` in `/example/y`)"
);
return {
exec: (
text: string,
offset: number,
tokens: IToken[],
groups: { [groupName: string]: IToken[] }
): RegExpExecArray | null => {
// start the search at the offset
pattern.lastIndex = offset;
const result = pattern.exec(text);
if (result) {
// Store the payload options in the regex result as the payload.
// Chevrotain will pick it up.
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
(result as any).payload = getPayload({
text,
offset,
tokens,
groups,
result,
});
}
return result;
},
};
}