extra-parser 0.6.5 → 0.7.0
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/README.md +16 -27
- package/lib/consume-node.d.ts +1 -1
- package/lib/consume-node.js +2 -2
- package/lib/consume-node.js.map +1 -1
- package/lib/create-binary-operator-expression-node-pattern.js +2 -2
- package/lib/create-binary-operator-expression-node-pattern.js.map +1 -1
- package/lib/create-grouped-expression-node-pattern.js +2 -2
- package/lib/create-grouped-expression-node-pattern.js.map +1 -1
- package/lib/create-unary-operator-expression-node-pattern.js +2 -2
- package/lib/create-unary-operator-expression-node-pattern.js.map +1 -1
- package/lib/match-any-of.d.ts +1 -1
- package/lib/match-any-of.js +2 -2
- package/lib/match-any-of.js.map +1 -1
- package/lib/match-repetitions.d.ts +1 -1
- package/lib/match-repetitions.js +15 -8
- package/lib/match-repetitions.js.map +1 -1
- package/lib/match-sequence.d.ts +1 -1
- package/lib/match-sequence.js +4 -4
- package/lib/match-sequence.js.map +1 -1
- package/lib/parse.d.ts +1 -1
- package/lib/parse.js +2 -2
- package/lib/parse.js.map +1 -1
- package/lib/tokenize.d.ts +1 -1
- package/lib/tokenize.js +2 -2
- package/lib/tokenize.js.map +1 -1
- package/lib/types.d.ts +5 -5
- package/package.json +1 -1
- package/src/consume-node.ts +3 -3
- package/src/create-binary-operator-expression-node-pattern.ts +2 -2
- package/src/create-grouped-expression-node-pattern.ts +2 -2
- package/src/create-unary-operator-expression-node-pattern.ts +2 -2
- package/src/match-any-of.ts +3 -3
- package/src/match-repetitions.ts +24 -10
- package/src/match-sequence.ts +5 -5
- package/src/parse.ts +3 -3
- package/src/tokenize.ts +3 -3
- package/src/types.ts +11 -11
package/README.md
CHANGED
|
@@ -8,17 +8,6 @@ npm install --save extra-parser
|
|
|
8
8
|
yarn add extra-parser
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
## FAQ
|
|
12
|
-
### Why are functions asynchronous?
|
|
13
|
-
Some parsers make heavy use of recursion,
|
|
14
|
-
and most JavaScript engines do not support tail-call optimization,
|
|
15
|
-
which leads to the possibility of stack overflow in programs.
|
|
16
|
-
|
|
17
|
-
Asynchronous functions are an escape route:
|
|
18
|
-
developers can change recursive functions to asynchronous recursive functions
|
|
19
|
-
to get their programs out of stack overflow problems
|
|
20
|
-
without significantly reducing readability.
|
|
21
|
-
|
|
22
11
|
## API
|
|
23
12
|
```ts
|
|
24
13
|
interface IToken {
|
|
@@ -41,11 +30,11 @@ interface INodePatternMatch<Node extends INode> {
|
|
|
41
30
|
}
|
|
42
31
|
|
|
43
32
|
interface ITokenPattern<Token extends IToken = IToken> {
|
|
44
|
-
(text: string):
|
|
33
|
+
(text: string): ITokenPatternMatch<Token> | Falsy
|
|
45
34
|
}
|
|
46
35
|
|
|
47
36
|
interface INodePattern<Token extends IToken = IToken, Node extends INode = INode> {
|
|
48
|
-
(tokens: ReadonlyArray<Token>):
|
|
37
|
+
(tokens: ReadonlyArray<Token>): INodePatternMatch<Node> | Falsy
|
|
49
38
|
}
|
|
50
39
|
|
|
51
40
|
type MapSequenceToPatterns<
|
|
@@ -54,12 +43,12 @@ type MapSequenceToPatterns<
|
|
|
54
43
|
, Node extends INode = INode
|
|
55
44
|
> = {
|
|
56
45
|
[Index in keyof Sequence]:
|
|
57
|
-
[Sequence[Index]] extends [infer
|
|
46
|
+
[Sequence[Index]] extends [infer TokenOrNode]
|
|
58
47
|
? (
|
|
59
|
-
|
|
48
|
+
TokenOrNode extends Token
|
|
60
49
|
? string
|
|
61
|
-
:
|
|
62
|
-
? INodePattern<Token,
|
|
50
|
+
: TokenOrNode extends Node
|
|
51
|
+
? INodePattern<Token, TokenOrNode>
|
|
63
52
|
: never
|
|
64
53
|
)
|
|
65
54
|
: never
|
|
@@ -71,12 +60,12 @@ type MapSequenceToMatches<
|
|
|
71
60
|
, Node extends INode = INode
|
|
72
61
|
> = {
|
|
73
62
|
[Index in keyof Sequence]:
|
|
74
|
-
[Sequence[Index]] extends [infer
|
|
63
|
+
[Sequence[Index]] extends [infer TokenOrNode]
|
|
75
64
|
? (
|
|
76
|
-
|
|
65
|
+
TokenOrNode extends IToken
|
|
77
66
|
? Token
|
|
78
|
-
:
|
|
79
|
-
? INodePatternMatch<
|
|
67
|
+
: TokenOrNode extends INode
|
|
68
|
+
? INodePatternMatch<TokenOrNode>
|
|
80
69
|
: never
|
|
81
70
|
)
|
|
82
71
|
: never
|
|
@@ -88,7 +77,7 @@ type MapSequenceToMatches<
|
|
|
88
77
|
function tokenize<Token extends IToken = IToken>(
|
|
89
78
|
patterns: Array<ITokenPattern<Token>>
|
|
90
79
|
, text: string
|
|
91
|
-
):
|
|
80
|
+
): IterableIterator<Token>
|
|
92
81
|
```
|
|
93
82
|
|
|
94
83
|
### parse
|
|
@@ -96,7 +85,7 @@ function tokenize<Token extends IToken = IToken>(
|
|
|
96
85
|
function parse<Token extends IToken = IToken, Node extends INode = INode>(
|
|
97
86
|
patterns: Array<INodePattern<Token, Node>>
|
|
98
87
|
, tokens: Token[]
|
|
99
|
-
):
|
|
88
|
+
): IterableIterator<Node>
|
|
100
89
|
```
|
|
101
90
|
|
|
102
91
|
### consumeNode
|
|
@@ -107,7 +96,7 @@ function consumeNode<
|
|
|
107
96
|
>(
|
|
108
97
|
nodePattern: INodePattern<Token, Node>
|
|
109
98
|
, tokens: Token[]
|
|
110
|
-
):
|
|
99
|
+
): INodePatternMatch<Node> | Falsy
|
|
111
100
|
```
|
|
112
101
|
|
|
113
102
|
### consumeToken
|
|
@@ -126,7 +115,7 @@ function matchAnyOf<
|
|
|
126
115
|
>(
|
|
127
116
|
nodePatterns: ReadonlyArray<INodePattern<Token, Node>>
|
|
128
117
|
, tokens: ReadonlyArray<Token>
|
|
129
|
-
):
|
|
118
|
+
): INodePatternMatch<Node> | Falsy
|
|
130
119
|
```
|
|
131
120
|
|
|
132
121
|
### matchSequence
|
|
@@ -138,7 +127,7 @@ function matchSequence<
|
|
|
138
127
|
>(
|
|
139
128
|
patterns: MapSequenceToPatterns<Sequence, Token, Node>
|
|
140
129
|
, tokens: ReadonlyArray<Token>
|
|
141
|
-
):
|
|
130
|
+
): MapSequenceToMatches<Sequence, Token, Node> | Falsy
|
|
142
131
|
```
|
|
143
132
|
|
|
144
133
|
### matchRepetitions
|
|
@@ -154,7 +143,7 @@ function matchRepetitions<
|
|
|
154
143
|
minimumRepetitions?: number = 1
|
|
155
144
|
maximumRepetitions?: number = Infinity
|
|
156
145
|
}
|
|
157
|
-
):
|
|
146
|
+
): Array<Token | INodePatternMatch<Node>> | Falsy
|
|
158
147
|
```
|
|
159
148
|
|
|
160
149
|
### createTokenPatternFromRegExp
|
package/lib/consume-node.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { Falsy } from '@blackglory/prelude';
|
|
2
2
|
import { IToken, INode, INodePattern, INodePatternMatch } from './types';
|
|
3
|
-
export declare function consumeNode<Token extends IToken = IToken, Node extends INode = INode>(nodePattern: INodePattern<Token, Node>, tokens: Token[]):
|
|
3
|
+
export declare function consumeNode<Token extends IToken = IToken, Node extends INode = INode>(nodePattern: INodePattern<Token, Node>, tokens: Token[]): INodePatternMatch<Node> | Falsy;
|
package/lib/consume-node.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.consumeNode = void 0;
|
|
4
4
|
const prelude_1 = require("@blackglory/prelude");
|
|
5
|
-
|
|
6
|
-
const match =
|
|
5
|
+
function consumeNode(nodePattern, tokens) {
|
|
6
|
+
const match = nodePattern(tokens);
|
|
7
7
|
if ((0, prelude_1.isntFalsy)(match)) {
|
|
8
8
|
tokens.splice(0, match.consumed);
|
|
9
9
|
return match;
|
package/lib/consume-node.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consume-node.js","sourceRoot":"","sources":["../src/consume-node.ts"],"names":[],"mappings":";;;AAAA,iDAAsD;
|
|
1
|
+
{"version":3,"file":"consume-node.js","sourceRoot":"","sources":["../src/consume-node.ts"],"names":[],"mappings":";;;AAAA,iDAAsD;AAQtD,SAAgB,WAAW,CAIzB,WAAsC,EACtC,MAAe;IAEf,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,CAAA;IAEjC,IAAI,IAAA,mBAAS,EAAC,KAAK,CAAC,EAAE;QACpB,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAA;QAChC,OAAO,KAAK,CAAA;KACb;AACH,CAAC;AAbD,kCAaC"}
|
|
@@ -4,8 +4,8 @@ exports.createBinaryOperatorExpressionNodePattern = void 0;
|
|
|
4
4
|
const prelude_1 = require("@blackglory/prelude");
|
|
5
5
|
const match_sequence_1 = require("./match-sequence");
|
|
6
6
|
function createBinaryOperatorExpressionNodePattern({ nodeType, centerTokenType, rightNodePattern, leftNodePattern }) {
|
|
7
|
-
return
|
|
8
|
-
const matches =
|
|
7
|
+
return tokens => {
|
|
8
|
+
const matches = (0, match_sequence_1.matchSequence)([
|
|
9
9
|
leftNodePattern,
|
|
10
10
|
centerTokenType,
|
|
11
11
|
rightNodePattern
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-binary-operator-expression-node-pattern.js","sourceRoot":"","sources":["../src/create-binary-operator-expression-node-pattern.ts"],"names":[],"mappings":";;;AAAA,iDAA+C;AAE/C,qDAAgD;AAYhD,SAAgB,yCAAyC,CAKvD,EAAE,QAAQ,EAAE,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAK/D;IAIC,OAAO,
|
|
1
|
+
{"version":3,"file":"create-binary-operator-expression-node-pattern.js","sourceRoot":"","sources":["../src/create-binary-operator-expression-node-pattern.ts"],"names":[],"mappings":";;;AAAA,iDAA+C;AAE/C,qDAAgD;AAYhD,SAAgB,yCAAyC,CAKvD,EAAE,QAAQ,EAAE,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAK/D;IAIC,OAAO,MAAM,CAAC,EAAE;QACd,MAAM,OAAO,GAAG,IAAA,8BAAa,EAC3B;YACE,eAAiD;YACjD,eAAe;YACf,gBAAmD;SACpD,EACD,MAAM,CACP,CAAA;QACD,IAAI,IAAA,mBAAS,EAAC,OAAO,CAAC,EAAE;YACtB,MAAM,CAAC,SAAS,EAAE,KAAK,EAAE,UAAU,CAAC,GAAG,OAAO,CAAA;YAC9C,OAAO;gBACL,QAAQ,EAAE,SAAS,CAAC,QAAQ,GAAG,CAAC,GAAG,UAAU,CAAC,QAAQ;gBACtD,IAAI,EAAE;oBACJ,QAAQ;oBACR,IAAI,EAAE,SAAS,CAAC,IAAoB;oBACpC,KAAK,EAAE,UAAU,CAAC,IAAqB;iBACxC;aACF,CAAA;SACF;IACH,CAAC,CAAA;AACH,CAAC;AAnCD,8FAmCC"}
|
|
@@ -4,8 +4,8 @@ exports.createGroupedExpressionNodePattern = void 0;
|
|
|
4
4
|
const prelude_1 = require("@blackglory/prelude");
|
|
5
5
|
const match_sequence_1 = require("./match-sequence");
|
|
6
6
|
function createGroupedExpressionNodePattern({ leftTokenType, rightTokenType, centerNodePattern }) {
|
|
7
|
-
return
|
|
8
|
-
const matches =
|
|
7
|
+
return tokens => {
|
|
8
|
+
const matches = (0, match_sequence_1.matchSequence)([
|
|
9
9
|
leftTokenType,
|
|
10
10
|
centerNodePattern,
|
|
11
11
|
rightTokenType
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-grouped-expression-node-pattern.js","sourceRoot":"","sources":["../src/create-grouped-expression-node-pattern.ts"],"names":[],"mappings":";;;AAAA,iDAA+C;AAE/C,qDAAgD;AAEhD,SAAgB,kCAAkC,CAGhD,EAAE,aAAa,EAAE,cAAc,EAAE,iBAAiB,EAInD;IACC,OAAO,
|
|
1
|
+
{"version":3,"file":"create-grouped-expression-node-pattern.js","sourceRoot":"","sources":["../src/create-grouped-expression-node-pattern.ts"],"names":[],"mappings":";;;AAAA,iDAA+C;AAE/C,qDAAgD;AAEhD,SAAgB,kCAAkC,CAGhD,EAAE,aAAa,EAAE,cAAc,EAAE,iBAAiB,EAInD;IACC,OAAO,MAAM,CAAC,EAAE;QACd,MAAM,OAAO,GAAG,IAAA,8BAAa,EAC3B;YACE,aAAa;YACb,iBAAqD;YACrD,cAAc;SACf,EACD,MAAM,CACP,CAAA;QACD,IAAI,IAAA,mBAAS,EAAC,OAAO,CAAC,EAAE;YACtB,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,UAAU,CAAC,GAAG,OAAO,CAAA;YAClD,OAAO;gBACL,QAAQ,EAAE,CAAC,GAAG,SAAS,CAAC,QAAQ,GAAG,CAAC;gBACpC,IAAI,EAAE,SAAS,CAAC,IAAkB;aACnC,CAAA;SACF;IACH,CAAC,CAAA;AACH,CAAC;AAzBD,gFAyBC"}
|
|
@@ -4,8 +4,8 @@ exports.createUnaryOperatorExpressionNodePattern = void 0;
|
|
|
4
4
|
const prelude_1 = require("@blackglory/prelude");
|
|
5
5
|
const match_sequence_1 = require("./match-sequence");
|
|
6
6
|
function createUnaryOperatorExpressionNodePattern({ leftTokenType, nodeType, rightNodePattern }) {
|
|
7
|
-
return
|
|
8
|
-
const matches =
|
|
7
|
+
return tokens => {
|
|
8
|
+
const matches = (0, match_sequence_1.matchSequence)([
|
|
9
9
|
leftTokenType,
|
|
10
10
|
rightNodePattern
|
|
11
11
|
], tokens);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-unary-operator-expression-node-pattern.js","sourceRoot":"","sources":["../src/create-unary-operator-expression-node-pattern.ts"],"names":[],"mappings":";;;AAAA,iDAA+C;AAE/C,qDAAgD;AAUhD,SAAgB,wCAAwC,CAItD,EAAE,aAAa,EAAE,QAAQ,EAAE,gBAAgB,EAI5C;IAIC,OAAO,
|
|
1
|
+
{"version":3,"file":"create-unary-operator-expression-node-pattern.js","sourceRoot":"","sources":["../src/create-unary-operator-expression-node-pattern.ts"],"names":[],"mappings":";;;AAAA,iDAA+C;AAE/C,qDAAgD;AAUhD,SAAgB,wCAAwC,CAItD,EAAE,aAAa,EAAE,QAAQ,EAAE,gBAAgB,EAI5C;IAIC,OAAO,MAAM,CAAC,EAAE;QACd,MAAM,OAAO,GAAG,IAAA,8BAAa,EAC3B;YACE,aAAa;YACb,gBAAmD;SACpD,EACD,MAAM,CACP,CAAA;QACD,IAAI,IAAA,mBAAS,EAAC,OAAO,CAAC,EAAE;YACtB,MAAM,CAAC,SAAS,EAAE,UAAU,CAAC,GAAG,OAAO,CAAA;YACvC,OAAO;gBACL,QAAQ,EAAE,CAAC,GAAG,UAAU,CAAC,QAAQ;gBACjC,IAAI,EAAE;oBACJ,QAAQ,EAAE,QAAQ;oBAClB,KAAK,EAAE,UAAU,CAAC,IAAiB;iBACpC;aACF,CAAA;SACF;IACH,CAAC,CAAA;AACH,CAAC;AA/BD,4FA+BC"}
|
package/lib/match-any-of.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { Falsy } from '@blackglory/prelude';
|
|
2
2
|
import { IToken, INode, INodePattern, INodePatternMatch } from './types';
|
|
3
|
-
export declare function matchAnyOf<Token extends IToken = IToken, Node extends INode = INode>(nodePatterns: ReadonlyArray<INodePattern<Token, Node>>, tokens: ReadonlyArray<Token>):
|
|
3
|
+
export declare function matchAnyOf<Token extends IToken = IToken, Node extends INode = INode>(nodePatterns: ReadonlyArray<INodePattern<Token, Node>>, tokens: ReadonlyArray<Token>): INodePatternMatch<Node> | Falsy;
|
package/lib/match-any-of.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.matchAnyOf = void 0;
|
|
4
4
|
const prelude_1 = require("@blackglory/prelude");
|
|
5
|
-
|
|
5
|
+
function matchAnyOf(nodePatterns, tokens) {
|
|
6
6
|
for (const pattern of nodePatterns) {
|
|
7
|
-
const match =
|
|
7
|
+
const match = pattern(tokens);
|
|
8
8
|
if ((0, prelude_1.isntFalsy)(match)) {
|
|
9
9
|
return match;
|
|
10
10
|
}
|
package/lib/match-any-of.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"match-any-of.js","sourceRoot":"","sources":["../src/match-any-of.ts"],"names":[],"mappings":";;;AAAA,iDAAsD;
|
|
1
|
+
{"version":3,"file":"match-any-of.js","sourceRoot":"","sources":["../src/match-any-of.ts"],"names":[],"mappings":";;;AAAA,iDAAsD;AAMtD,SAAgB,UAAU,CAIxB,YAAsD,EACtD,MAA4B;IAE5B,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE;QAClC,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;QAC7B,IAAI,IAAA,mBAAS,EAAC,KAAK,CAAC,EAAE;YACpB,OAAO,KAAK,CAAA;SACb;KACF;AACH,CAAC;AAbD,gCAaC"}
|
|
@@ -3,4 +3,4 @@ import { IToken, INode, MapSequenceToPatterns, INodePatternMatch } from './types
|
|
|
3
3
|
export declare function matchRepetitions<Sequence extends ReadonlyArray<Token | Node>, Token extends IToken = IToken, Node extends INode = INode>(patterns: MapSequenceToPatterns<Sequence, Token, Node>, tokens: ReadonlyArray<Token>, { minimumRepetitions, maximumRepetitions }?: {
|
|
4
4
|
minimumRepetitions?: number;
|
|
5
5
|
maximumRepetitions?: number;
|
|
6
|
-
}):
|
|
6
|
+
}): Array<Token | INodePatternMatch<Node>> | Falsy;
|
package/lib/match-repetitions.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.matchRepetitions = void 0;
|
|
4
4
|
const prelude_1 = require("@blackglory/prelude");
|
|
5
5
|
const match_sequence_1 = require("./match-sequence");
|
|
6
|
-
|
|
6
|
+
function matchRepetitions(patterns, tokens, { minimumRepetitions = 1, maximumRepetitions = Infinity } = {}) {
|
|
7
7
|
(0, prelude_1.assert)(Number.isInteger(minimumRepetitions), 'The minimum repetiions must be an integer');
|
|
8
8
|
(0, prelude_1.assert)(minimumRepetitions >= 0, 'The minimum repetitions must be greater than or equal to 0');
|
|
9
9
|
(0, prelude_1.assert)(Number.isInteger(maximumRepetitions) || maximumRepetitions === Infinity, 'The maxmium repetiions must be an integer or an Infinity');
|
|
@@ -11,26 +11,33 @@ async function matchRepetitions(patterns, tokens, { minimumRepetitions = 1, maxi
|
|
|
11
11
|
const results = [];
|
|
12
12
|
const mutableTokens = (0, prelude_1.toArray)(tokens);
|
|
13
13
|
for (let i = 0; i < minimumRepetitions; i++) {
|
|
14
|
-
const matches =
|
|
14
|
+
const matches = (0, match_sequence_1.matchSequence)(patterns, mutableTokens);
|
|
15
15
|
if ((0, prelude_1.isntFalsy)(matches)) {
|
|
16
|
-
|
|
17
|
-
mutableTokens.splice(0, matches.length);
|
|
16
|
+
handleMatches(matches);
|
|
18
17
|
}
|
|
19
18
|
else {
|
|
20
19
|
return;
|
|
21
20
|
}
|
|
22
21
|
}
|
|
23
22
|
for (let i = minimumRepetitions; i < maximumRepetitions; i++) {
|
|
24
|
-
const matches =
|
|
23
|
+
const matches = (0, match_sequence_1.matchSequence)(patterns, mutableTokens);
|
|
25
24
|
if ((0, prelude_1.isntFalsy)(matches)) {
|
|
26
|
-
|
|
27
|
-
mutableTokens.splice(0, matches.length);
|
|
25
|
+
handleMatches(matches);
|
|
28
26
|
}
|
|
29
27
|
else {
|
|
30
28
|
break;
|
|
31
29
|
}
|
|
32
30
|
}
|
|
33
|
-
return results
|
|
31
|
+
return results;
|
|
32
|
+
function handleMatches(matches) {
|
|
33
|
+
results.push(...matches);
|
|
34
|
+
mutableTokens.splice(0, getConsumed(matches));
|
|
35
|
+
}
|
|
34
36
|
}
|
|
35
37
|
exports.matchRepetitions = matchRepetitions;
|
|
38
|
+
function getConsumed(matches) {
|
|
39
|
+
return matches
|
|
40
|
+
.map(match => 'consumed' in match ? match.consumed : 1)
|
|
41
|
+
.reduce((acc, cur) => acc + cur);
|
|
42
|
+
}
|
|
36
43
|
//# sourceMappingURL=match-repetitions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"match-repetitions.js","sourceRoot":"","sources":["../src/match-repetitions.ts"],"names":[],"mappings":";;;AAAA,iDAAuE;AAEvE,qDAAgD;
|
|
1
|
+
{"version":3,"file":"match-repetitions.js","sourceRoot":"","sources":["../src/match-repetitions.ts"],"names":[],"mappings":";;;AAAA,iDAAuE;AAEvE,qDAAgD;AAEhD,SAAgB,gBAAgB,CAK9B,QAAsD,EACtD,MAA4B,EAC5B,EACE,kBAAkB,GAAG,CAAC,EACtB,kBAAkB,GAAG,QAAQ,KAI3B,EAAE;IAEN,IAAA,gBAAM,EAAC,MAAM,CAAC,SAAS,CAAC,kBAAkB,CAAC,EAAE,2CAA2C,CAAC,CAAA;IACzF,IAAA,gBAAM,EACJ,kBAAkB,IAAI,CAAC,EACvB,4DAA4D,CAC7D,CAAA;IACD,IAAA,gBAAM,EACJ,MAAM,CAAC,SAAS,CAAC,kBAAkB,CAAC,IAAI,kBAAkB,KAAK,QAAQ,EACvE,0DAA0D,CAC3D,CAAA;IACD,IAAA,gBAAM,EACJ,kBAAkB,IAAI,kBAAkB,EACxC,kFAAkF,CACnF,CAAA;IAED,MAAM,OAAO,GAA2C,EAAE,CAAA;IAC1D,MAAM,aAAa,GAAG,IAAA,iBAAO,EAAC,MAAM,CAAC,CAAA;IAErC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,kBAAkB,EAAE,CAAC,EAAE,EAAE;QAC3C,MAAM,OAAO,GAAG,IAAA,8BAAa,EAAC,QAAQ,EAAE,aAAa,CAAC,CAAA;QACtD,IAAI,IAAA,mBAAS,EAAC,OAAO,CAAC,EAAE;YACtB,aAAa,CAAC,OAAO,CAAC,CAAA;SACvB;aAAM;YACL,OAAM;SACP;KACF;IAED,KAAK,IAAI,CAAC,GAAG,kBAAkB,EAAE,CAAC,GAAG,kBAAkB,EAAE,CAAC,EAAE,EAAE;QAC5D,MAAM,OAAO,GAAG,IAAA,8BAAa,EAAC,QAAQ,EAAE,aAAa,CAAC,CAAA;QACtD,IAAI,IAAA,mBAAS,EAAC,OAAO,CAAC,EAAE;YACtB,aAAa,CAAC,OAAO,CAAC,CAAA;SACvB;aAAM;YACL,MAAK;SACN;KACF;IAED,OAAO,OAAO,CAAA;IAEd,SAAS,aAAa,CACpB,OAAoD;QAEpD,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAA;QACxB,aAAa,CAAC,MAAM,CAClB,CAAC,EACD,WAAW,CAAC,OAAiD,CAAC,CAC/D,CAAA;IACH,CAAC;AACH,CAAC;AA7DD,4CA6DC;AAED,SAAS,WAAW,CAAC,OAAiD;IACpE,OAAO,OAAO;SACX,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;SACtD,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,GAAG,CAAC,CAAA;AACpC,CAAC"}
|
package/lib/match-sequence.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NonEmptyArray, Falsy } from '@blackglory/prelude';
|
|
2
2
|
import { IToken, INode, INodePattern, MapSequenceToPatterns, MapSequenceToMatches } from './types';
|
|
3
|
-
export declare function matchSequence<Sequence extends ReadonlyArray<Token | Node>, Token extends IToken = IToken, Node extends INode = INode>(patterns: MapSequenceToPatterns<Sequence, Token, Node>, tokens: ReadonlyArray<Token>):
|
|
3
|
+
export declare function matchSequence<Sequence extends ReadonlyArray<Token | Node>, Token extends IToken = IToken, Node extends INode = INode>(patterns: MapSequenceToPatterns<Sequence, Token, Node>, tokens: ReadonlyArray<Token>): MapSequenceToMatches<Sequence, Token, Node> | Falsy;
|
|
4
4
|
declare type SubPatterns<Token extends IToken = IToken, Node extends INode = INode> = [INodePattern<Token, Node>, string] | NonEmptyArray<string> | NonEmptyArray<INodePattern<Token, Node>>;
|
|
5
5
|
export declare function splitPatterns<Sequence extends ReadonlyArray<Token | Node>, Token extends IToken = IToken, Node extends INode = INode>(patterns: MapSequenceToPatterns<Sequence, Token, Node>): IterableIterator<SubPatterns<Token, Node>>;
|
|
6
6
|
export {};
|
package/lib/match-sequence.js
CHANGED
|
@@ -5,7 +5,7 @@ const prelude_1 = require("@blackglory/prelude");
|
|
|
5
5
|
const iterable_operator_1 = require("iterable-operator");
|
|
6
6
|
const consume_token_1 = require("./consume-token");
|
|
7
7
|
const consume_node_1 = require("./consume-node");
|
|
8
|
-
|
|
8
|
+
function matchSequence(patterns, tokens) {
|
|
9
9
|
if (isTokenTypes(patterns)) {
|
|
10
10
|
const matches = [];
|
|
11
11
|
const mutableTokens = (0, prelude_1.toArray)(tokens);
|
|
@@ -24,7 +24,7 @@ async function matchSequence(patterns, tokens) {
|
|
|
24
24
|
const matches = [];
|
|
25
25
|
const mutableTokens = (0, prelude_1.toArray)(tokens);
|
|
26
26
|
for (const pattern of patterns) {
|
|
27
|
-
const match =
|
|
27
|
+
const match = (0, consume_node_1.consumeNode)(pattern, mutableTokens);
|
|
28
28
|
if ((0, prelude_1.isntFalsy)(match)) {
|
|
29
29
|
matches.push(match);
|
|
30
30
|
}
|
|
@@ -38,7 +38,7 @@ async function matchSequence(patterns, tokens) {
|
|
|
38
38
|
const [nodePattern, tokenType] = patterns;
|
|
39
39
|
for (const indexOfToken of (0, iterable_operator_1.findAllIndexes)(tokens, x => x.tokenType === tokenType)) {
|
|
40
40
|
const leftTokens = tokens.slice(0, indexOfToken);
|
|
41
|
-
const leftMatch =
|
|
41
|
+
const leftMatch = nodePattern(leftTokens);
|
|
42
42
|
if ((0, prelude_1.isntFalsy)(leftMatch) &&
|
|
43
43
|
leftMatch.consumed === indexOfToken) {
|
|
44
44
|
const matches = [
|
|
@@ -53,7 +53,7 @@ async function matchSequence(patterns, tokens) {
|
|
|
53
53
|
const matches = [];
|
|
54
54
|
const remainingTokens = (0, prelude_1.toArray)(tokens);
|
|
55
55
|
for (const subPatterns of splitPatterns(patterns)) {
|
|
56
|
-
const subMatches =
|
|
56
|
+
const subMatches = matchSequence(subPatterns, remainingTokens);
|
|
57
57
|
if ((0, prelude_1.isntFalsy)(subMatches)) {
|
|
58
58
|
const consumed = subMatches
|
|
59
59
|
.map((match) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"match-sequence.js","sourceRoot":"","sources":["../src/match-sequence.ts"],"names":[],"mappings":";;;AAAA,iDAO4B;AAC5B,yDAAkD;AASlD,mDAA8C;AAC9C,iDAA4C;
|
|
1
|
+
{"version":3,"file":"match-sequence.js","sourceRoot":"","sources":["../src/match-sequence.ts"],"names":[],"mappings":"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"}
|
package/lib/parse.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { IToken, INodePattern, INode } from './types';
|
|
2
|
-
export declare function parse<Token extends IToken = IToken, Node extends INode = INode>(patterns: Array<INodePattern<Token, Node>>, tokens: Token[]):
|
|
2
|
+
export declare function parse<Token extends IToken = IToken, Node extends INode = INode>(patterns: Array<INodePattern<Token, Node>>, tokens: Token[]): IterableIterator<Node>;
|
package/lib/parse.js
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parse = void 0;
|
|
4
4
|
const prelude_1 = require("@blackglory/prelude");
|
|
5
|
-
|
|
5
|
+
function* parse(patterns, tokens) {
|
|
6
6
|
let i = 0;
|
|
7
7
|
loop: while (i < tokens.length) {
|
|
8
8
|
const remainingTokens = tokens.slice(i);
|
|
9
9
|
for (const pattern of patterns) {
|
|
10
|
-
const result =
|
|
10
|
+
const result = pattern(remainingTokens);
|
|
11
11
|
if ((0, prelude_1.isntFalsy)(result)) {
|
|
12
12
|
yield result.node;
|
|
13
13
|
i += result.consumed;
|
package/lib/parse.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":";;;AAAA,iDAA+C;
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":";;;AAAA,iDAA+C;AAG/C,QAAe,CAAC,CAAC,KAAK,CAIpB,QAA0C,EAC1C,MAAe;IAEf,IAAI,CAAC,GAAG,CAAC,CAAA;IACT,IAAI,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE;QAC9B,MAAM,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAEvC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;YAC9B,MAAM,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAA;YACvC,IAAI,IAAA,mBAAS,EAAC,MAAM,CAAC,EAAE;gBACrB,MAAM,MAAM,CAAC,IAAI,CAAA;gBACjB,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAA;gBACpB,SAAS,IAAI,CAAA;aACd;SACF;QAED,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,EAAE,CAAC,CAAA;KAC1E;AACH,CAAC;AAtBD,sBAsBC"}
|
package/lib/tokenize.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { ITokenPattern, IToken } from './types';
|
|
2
|
-
export declare function tokenize<Token extends IToken = IToken>(patterns: Array<ITokenPattern<Token>>, text: string):
|
|
2
|
+
export declare function tokenize<Token extends IToken = IToken>(patterns: Array<ITokenPattern<Token>>, text: string): IterableIterator<Token>;
|
package/lib/tokenize.js
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.tokenize = void 0;
|
|
4
4
|
const prelude_1 = require("@blackglory/prelude");
|
|
5
|
-
|
|
5
|
+
function* tokenize(patterns, text) {
|
|
6
6
|
let i = 0;
|
|
7
7
|
loop: while (i < text.length) {
|
|
8
8
|
const remainingText = text.slice(i);
|
|
9
9
|
for (const pattern of patterns) {
|
|
10
|
-
const result =
|
|
10
|
+
const result = pattern(remainingText);
|
|
11
11
|
if ((0, prelude_1.isntFalsy)(result)) {
|
|
12
12
|
yield result.token;
|
|
13
13
|
i += result.consumed;
|
package/lib/tokenize.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokenize.js","sourceRoot":"","sources":["../src/tokenize.ts"],"names":[],"mappings":";;;AAAA,iDAA+C;
|
|
1
|
+
{"version":3,"file":"tokenize.js","sourceRoot":"","sources":["../src/tokenize.ts"],"names":[],"mappings":";;;AAAA,iDAA+C;AAG/C,QAAe,CAAC,CAAC,QAAQ,CACvB,QAAqC,EACrC,IAAY;IAEZ,IAAI,CAAC,GAAG,CAAC,CAAA;IACT,IAAI,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE;QAC5B,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAEnC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;YAC9B,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAA;YACrC,IAAI,IAAA,mBAAS,EAAC,MAAM,CAAC,EAAE;gBACrB,MAAM,MAAM,CAAC,KAAK,CAAA;gBAClB,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAA;gBACpB,SAAS,IAAI,CAAA;aACd;SACF;QAED,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,EAAE,CAAC,CAAA;KAClE;AACH,CAAC;AAnBD,4BAmBC"}
|
package/lib/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Falsy
|
|
1
|
+
import { Falsy } from '@blackglory/prelude';
|
|
2
2
|
export interface IToken {
|
|
3
3
|
tokenType: string;
|
|
4
4
|
value: string;
|
|
@@ -15,18 +15,18 @@ export interface INodePatternMatch<Node extends INode> {
|
|
|
15
15
|
node: Node;
|
|
16
16
|
}
|
|
17
17
|
export interface ITokenPattern<Token extends IToken = IToken> {
|
|
18
|
-
(text: string):
|
|
18
|
+
(text: string): ITokenPatternMatch<Token> | Falsy;
|
|
19
19
|
}
|
|
20
20
|
export interface INodePattern<Token extends IToken = IToken, Node extends INode = INode> {
|
|
21
|
-
(tokens: ReadonlyArray<Token>):
|
|
21
|
+
(tokens: ReadonlyArray<Token>): INodePatternMatch<Node> | Falsy;
|
|
22
22
|
}
|
|
23
23
|
export declare type MapSequenceToPatterns<Sequence extends ReadonlyArray<Token | Node>, Token extends IToken = IToken, Node extends INode = INode> = {
|
|
24
24
|
[Index in keyof Sequence]: [
|
|
25
25
|
Sequence[Index]
|
|
26
|
-
] extends [infer
|
|
26
|
+
] extends [infer TokenOrNode] ? (TokenOrNode extends Token ? string : TokenOrNode extends Node ? INodePattern<Token, TokenOrNode> : never) : never;
|
|
27
27
|
};
|
|
28
28
|
export declare type MapSequenceToMatches<Sequence extends ReadonlyArray<Token | Node>, Token extends IToken = IToken, Node extends INode = INode> = {
|
|
29
29
|
[Index in keyof Sequence]: [
|
|
30
30
|
Sequence[Index]
|
|
31
|
-
] extends [infer
|
|
31
|
+
] extends [infer TokenOrNode] ? (TokenOrNode extends IToken ? Token : TokenOrNode extends INode ? INodePatternMatch<TokenOrNode> : never) : never;
|
|
32
32
|
};
|
package/package.json
CHANGED
package/src/consume-node.ts
CHANGED
|
@@ -6,14 +6,14 @@ import { IToken, INode, INodePattern, INodePatternMatch } from './types'
|
|
|
6
6
|
*
|
|
7
7
|
* @param tokens 匹配成功时会发生原地修改
|
|
8
8
|
*/
|
|
9
|
-
export
|
|
9
|
+
export function consumeNode<
|
|
10
10
|
Token extends IToken = IToken
|
|
11
11
|
, Node extends INode = INode
|
|
12
12
|
>(
|
|
13
13
|
nodePattern: INodePattern<Token, Node>
|
|
14
14
|
, tokens: Token[]
|
|
15
|
-
):
|
|
16
|
-
const match =
|
|
15
|
+
): INodePatternMatch<Node> | Falsy {
|
|
16
|
+
const match = nodePattern(tokens)
|
|
17
17
|
|
|
18
18
|
if (isntFalsy(match)) {
|
|
19
19
|
tokens.splice(0, match.consumed)
|
|
@@ -26,8 +26,8 @@ export function createBinaryOperatorExpressionNodePattern<
|
|
|
26
26
|
Token
|
|
27
27
|
, IBinaryOperatorExpressionNode<Node['nodeType'], Node['left'], Node['right']>
|
|
28
28
|
> {
|
|
29
|
-
return
|
|
30
|
-
const matches =
|
|
29
|
+
return tokens => {
|
|
30
|
+
const matches = matchSequence<[INode, IToken, INode]>(
|
|
31
31
|
[
|
|
32
32
|
leftNodePattern as INodePattern<IToken, LeftNode>
|
|
33
33
|
, centerTokenType
|
|
@@ -10,8 +10,8 @@ export function createGroupedExpressionNodePattern<
|
|
|
10
10
|
rightTokenType: string
|
|
11
11
|
centerNodePattern: INodePattern<Token, CenterNode>
|
|
12
12
|
}): INodePattern<Token, CenterNode> {
|
|
13
|
-
return
|
|
14
|
-
const matches =
|
|
13
|
+
return tokens => {
|
|
14
|
+
const matches = matchSequence<[IToken, INode, IToken]>(
|
|
15
15
|
[
|
|
16
16
|
leftTokenType
|
|
17
17
|
, centerNodePattern as INodePattern<IToken, CenterNode>
|
|
@@ -22,8 +22,8 @@ export function createUnaryOperatorExpressionNodePattern<
|
|
|
22
22
|
Token
|
|
23
23
|
, IUnaryOperatorExpressionNode<Node['nodeType'], Node['right']>
|
|
24
24
|
> {
|
|
25
|
-
return
|
|
26
|
-
const matches =
|
|
25
|
+
return tokens => {
|
|
26
|
+
const matches = matchSequence<[IToken, INode]>(
|
|
27
27
|
[
|
|
28
28
|
leftTokenType
|
|
29
29
|
, rightNodePattern as INodePattern<IToken, RightNode>
|
package/src/match-any-of.ts
CHANGED
|
@@ -4,15 +4,15 @@ import { IToken, INode, INodePattern, INodePatternMatch } from './types'
|
|
|
4
4
|
/**
|
|
5
5
|
* 从多个模式中依序匹配, 直到有一个匹配结果为真值, 返回该真值.
|
|
6
6
|
*/
|
|
7
|
-
export
|
|
7
|
+
export function matchAnyOf<
|
|
8
8
|
Token extends IToken = IToken
|
|
9
9
|
, Node extends INode = INode
|
|
10
10
|
>(
|
|
11
11
|
nodePatterns: ReadonlyArray<INodePattern<Token, Node>>
|
|
12
12
|
, tokens: ReadonlyArray<Token>
|
|
13
|
-
):
|
|
13
|
+
): INodePatternMatch<Node> | Falsy {
|
|
14
14
|
for (const pattern of nodePatterns) {
|
|
15
|
-
const match =
|
|
15
|
+
const match = pattern(tokens)
|
|
16
16
|
if (isntFalsy(match)) {
|
|
17
17
|
return match
|
|
18
18
|
}
|
package/src/match-repetitions.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { assert, Falsy, isntFalsy, toArray } from '@blackglory/prelude'
|
|
|
2
2
|
import { IToken, INode, MapSequenceToPatterns, MapSequenceToMatches, INodePatternMatch } from './types'
|
|
3
3
|
import { matchSequence } from './match-sequence'
|
|
4
4
|
|
|
5
|
-
export
|
|
5
|
+
export function matchRepetitions<
|
|
6
6
|
Sequence extends ReadonlyArray<Token | Node>
|
|
7
7
|
, Token extends IToken = IToken
|
|
8
8
|
, Node extends INode = INode
|
|
@@ -16,7 +16,7 @@ export async function matchRepetitions<
|
|
|
16
16
|
minimumRepetitions?: number
|
|
17
17
|
maximumRepetitions?: number
|
|
18
18
|
} = {}
|
|
19
|
-
):
|
|
19
|
+
): Array<Token | INodePatternMatch<Node>> | Falsy {
|
|
20
20
|
assert(Number.isInteger(minimumRepetitions), 'The minimum repetiions must be an integer')
|
|
21
21
|
assert(
|
|
22
22
|
minimumRepetitions >= 0
|
|
@@ -31,28 +31,42 @@ export async function matchRepetitions<
|
|
|
31
31
|
, 'The maximum repetitions must be greater than or equal to the minimum repetitions'
|
|
32
32
|
)
|
|
33
33
|
|
|
34
|
-
const results: Array<
|
|
34
|
+
const results: Array<Token | INodePatternMatch<Node>> = []
|
|
35
35
|
const mutableTokens = toArray(tokens)
|
|
36
36
|
|
|
37
37
|
for (let i = 0; i < minimumRepetitions; i++) {
|
|
38
|
-
const matches =
|
|
38
|
+
const matches = matchSequence(patterns, mutableTokens)
|
|
39
39
|
if (isntFalsy(matches)) {
|
|
40
|
-
|
|
41
|
-
mutableTokens.splice(0, matches.length)
|
|
40
|
+
handleMatches(matches)
|
|
42
41
|
} else {
|
|
43
42
|
return
|
|
44
43
|
}
|
|
45
44
|
}
|
|
46
45
|
|
|
47
46
|
for (let i = minimumRepetitions; i < maximumRepetitions; i++) {
|
|
48
|
-
const matches =
|
|
47
|
+
const matches = matchSequence(patterns, mutableTokens)
|
|
49
48
|
if (isntFalsy(matches)) {
|
|
50
|
-
|
|
51
|
-
mutableTokens.splice(0, matches.length)
|
|
49
|
+
handleMatches(matches)
|
|
52
50
|
} else {
|
|
53
51
|
break
|
|
54
52
|
}
|
|
55
53
|
}
|
|
56
54
|
|
|
57
|
-
return results
|
|
55
|
+
return results
|
|
56
|
+
|
|
57
|
+
function handleMatches(
|
|
58
|
+
matches: MapSequenceToMatches<Sequence, Token, Node>
|
|
59
|
+
): void {
|
|
60
|
+
results.push(...matches)
|
|
61
|
+
mutableTokens.splice(
|
|
62
|
+
0
|
|
63
|
+
, getConsumed(matches as Array<Token | INodePatternMatch<Node>>)
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function getConsumed(matches: Array<IToken | INodePatternMatch<INode>>): number {
|
|
69
|
+
return matches
|
|
70
|
+
.map(match => 'consumed' in match ? match.consumed : 1)
|
|
71
|
+
.reduce((acc, cur) => acc + cur)
|
|
58
72
|
}
|
package/src/match-sequence.ts
CHANGED
|
@@ -27,14 +27,14 @@ import { consumeNode } from './consume-node'
|
|
|
27
27
|
* 这种子模式适用于二元或三元运算符这样的规则.
|
|
28
28
|
* 在引擎盖下, 它首先匹配TokenType以防止NodePattern在匹配时陷入死循环.
|
|
29
29
|
*/
|
|
30
|
-
export
|
|
30
|
+
export function matchSequence<
|
|
31
31
|
Sequence extends ReadonlyArray<Token | Node>
|
|
32
32
|
, Token extends IToken = IToken
|
|
33
33
|
, Node extends INode = INode
|
|
34
34
|
>(
|
|
35
35
|
patterns: MapSequenceToPatterns<Sequence, Token, Node>
|
|
36
36
|
, tokens: ReadonlyArray<Token>
|
|
37
|
-
):
|
|
37
|
+
): MapSequenceToMatches<Sequence, Token, Node> | Falsy {
|
|
38
38
|
if (isTokenTypes(patterns)) {
|
|
39
39
|
const matches: Array<Token> = []
|
|
40
40
|
|
|
@@ -54,7 +54,7 @@ export async function matchSequence<
|
|
|
54
54
|
|
|
55
55
|
const mutableTokens = toArray(tokens)
|
|
56
56
|
for (const pattern of patterns) {
|
|
57
|
-
const match =
|
|
57
|
+
const match = consumeNode(pattern, mutableTokens)
|
|
58
58
|
if (isntFalsy(match)) {
|
|
59
59
|
matches.push(match)
|
|
60
60
|
} else {
|
|
@@ -70,7 +70,7 @@ export async function matchSequence<
|
|
|
70
70
|
const indexOfToken of findAllIndexes(tokens, x => x.tokenType === tokenType)
|
|
71
71
|
) {
|
|
72
72
|
const leftTokens = tokens.slice(0, indexOfToken)
|
|
73
|
-
const leftMatch =
|
|
73
|
+
const leftMatch = nodePattern(leftTokens)
|
|
74
74
|
if (
|
|
75
75
|
isntFalsy(leftMatch) &&
|
|
76
76
|
leftMatch.consumed === indexOfToken
|
|
@@ -86,7 +86,7 @@ export async function matchSequence<
|
|
|
86
86
|
const matches: Array<INodePatternMatch<Node> | Token> = []
|
|
87
87
|
const remainingTokens = toArray(tokens)
|
|
88
88
|
for (const subPatterns of splitPatterns(patterns)) {
|
|
89
|
-
const subMatches =
|
|
89
|
+
const subMatches = matchSequence(
|
|
90
90
|
subPatterns as MapSequenceToPatterns<Sequence, Token, Node>
|
|
91
91
|
, remainingTokens
|
|
92
92
|
)
|
package/src/parse.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { isntFalsy } from '@blackglory/prelude'
|
|
2
2
|
import { IToken, INodePattern, INode } from './types'
|
|
3
3
|
|
|
4
|
-
export
|
|
4
|
+
export function* parse<
|
|
5
5
|
Token extends IToken = IToken
|
|
6
6
|
, Node extends INode = INode
|
|
7
7
|
>(
|
|
8
8
|
patterns: Array<INodePattern<Token, Node>>
|
|
9
9
|
, tokens: Token[]
|
|
10
|
-
):
|
|
10
|
+
): IterableIterator<Node> {
|
|
11
11
|
let i = 0
|
|
12
12
|
loop: while (i < tokens.length) {
|
|
13
13
|
const remainingTokens = tokens.slice(i)
|
|
14
14
|
|
|
15
15
|
for (const pattern of patterns) {
|
|
16
|
-
const result =
|
|
16
|
+
const result = pattern(remainingTokens)
|
|
17
17
|
if (isntFalsy(result)) {
|
|
18
18
|
yield result.node
|
|
19
19
|
i += result.consumed
|
package/src/tokenize.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { isntFalsy } from '@blackglory/prelude'
|
|
2
2
|
import { ITokenPattern, IToken } from './types'
|
|
3
3
|
|
|
4
|
-
export
|
|
4
|
+
export function* tokenize<Token extends IToken = IToken>(
|
|
5
5
|
patterns: Array<ITokenPattern<Token>>
|
|
6
6
|
, text: string
|
|
7
|
-
):
|
|
7
|
+
): IterableIterator<Token> {
|
|
8
8
|
let i = 0
|
|
9
9
|
loop: while (i < text.length) {
|
|
10
10
|
const remainingText = text.slice(i)
|
|
11
11
|
|
|
12
12
|
for (const pattern of patterns) {
|
|
13
|
-
const result =
|
|
13
|
+
const result = pattern(remainingText)
|
|
14
14
|
if (isntFalsy(result)) {
|
|
15
15
|
yield result.token
|
|
16
16
|
i += result.consumed
|
package/src/types.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Falsy
|
|
1
|
+
import { Falsy } from '@blackglory/prelude'
|
|
2
2
|
|
|
3
3
|
export interface IToken {
|
|
4
4
|
tokenType: string
|
|
@@ -20,14 +20,14 @@ export interface INodePatternMatch<Node extends INode> {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export interface ITokenPattern<Token extends IToken = IToken> {
|
|
23
|
-
(text: string):
|
|
23
|
+
(text: string): ITokenPatternMatch<Token> | Falsy
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
export interface INodePattern<
|
|
27
27
|
Token extends IToken = IToken
|
|
28
28
|
, Node extends INode = INode
|
|
29
29
|
> {
|
|
30
|
-
(tokens: ReadonlyArray<Token>):
|
|
30
|
+
(tokens: ReadonlyArray<Token>): INodePatternMatch<Node> | Falsy
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
export type MapSequenceToPatterns<
|
|
@@ -36,12 +36,12 @@ export type MapSequenceToPatterns<
|
|
|
36
36
|
, Node extends INode = INode
|
|
37
37
|
> = {
|
|
38
38
|
[Index in keyof Sequence]:
|
|
39
|
-
[Sequence[Index]] extends [infer
|
|
39
|
+
[Sequence[Index]] extends [infer TokenOrNode]
|
|
40
40
|
? (
|
|
41
|
-
|
|
41
|
+
TokenOrNode extends Token
|
|
42
42
|
? string
|
|
43
|
-
:
|
|
44
|
-
? INodePattern<Token,
|
|
43
|
+
: TokenOrNode extends Node
|
|
44
|
+
? INodePattern<Token, TokenOrNode>
|
|
45
45
|
: never
|
|
46
46
|
)
|
|
47
47
|
: never
|
|
@@ -53,12 +53,12 @@ export type MapSequenceToMatches<
|
|
|
53
53
|
, Node extends INode = INode
|
|
54
54
|
> = {
|
|
55
55
|
[Index in keyof Sequence]:
|
|
56
|
-
[Sequence[Index]] extends [infer
|
|
56
|
+
[Sequence[Index]] extends [infer TokenOrNode]
|
|
57
57
|
? (
|
|
58
|
-
|
|
58
|
+
TokenOrNode extends IToken
|
|
59
59
|
? Token
|
|
60
|
-
:
|
|
61
|
-
? INodePatternMatch<
|
|
60
|
+
: TokenOrNode extends INode
|
|
61
|
+
? INodePatternMatch<TokenOrNode>
|
|
62
62
|
: never
|
|
63
63
|
)
|
|
64
64
|
: never
|