securemark 0.295.0 → 0.295.2
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/CHANGELOG.md +8 -0
- package/design.md +4 -3
- package/dist/index.js +529 -484
- package/markdown.d.ts +13 -28
- package/package.json +1 -1
- package/src/combinator/control/constraint/block.test.ts +6 -8
- package/src/combinator/control/constraint/contract.ts +7 -7
- package/src/combinator/control/constraint/line.test.ts +7 -9
- package/src/combinator/control/constraint/line.ts +0 -1
- package/src/combinator/control/manipulation/clear.ts +2 -2
- package/src/combinator/control/manipulation/convert.ts +3 -3
- package/src/combinator/control/manipulation/duplicate.ts +4 -4
- package/src/combinator/control/manipulation/fallback.ts +2 -2
- package/src/combinator/control/manipulation/fence.ts +3 -3
- package/src/combinator/control/manipulation/indent.test.ts +20 -22
- package/src/combinator/control/manipulation/indent.ts +2 -2
- package/src/combinator/control/manipulation/recovery.ts +3 -3
- package/src/combinator/control/manipulation/reverse.ts +2 -2
- package/src/combinator/control/manipulation/scope.ts +2 -4
- package/src/combinator/control/manipulation/surround.ts +66 -66
- package/src/combinator/control/monad/bind.ts +6 -6
- package/src/combinator/control/monad/fmap.ts +6 -6
- package/src/combinator/data/data.ts +2 -2
- package/src/combinator/data/{parser/context/delimiter.ts → delimiter.ts} +4 -4
- package/src/combinator/data/parser/context.test.ts +12 -11
- package/src/combinator/data/parser/context.ts +13 -14
- package/src/combinator/data/parser/inits.ts +5 -5
- package/src/combinator/data/parser/sequence.test.ts +12 -13
- package/src/combinator/data/parser/sequence.ts +5 -5
- package/src/combinator/data/parser/some.test.ts +15 -16
- package/src/combinator/data/parser/some.ts +5 -6
- package/src/combinator/data/parser/subsequence.test.ts +16 -17
- package/src/combinator/data/parser/subsequence.ts +3 -3
- package/src/combinator/data/parser/tails.ts +3 -3
- package/src/combinator/data/parser/union.test.ts +12 -13
- package/src/combinator/data/parser/union.ts +3 -3
- package/src/combinator/data/parser.ts +55 -32
- package/src/debug.test.ts +5 -3
- package/src/parser/api/bind.ts +8 -6
- package/src/parser/api/header.ts +4 -4
- package/src/parser/api/normalize.ts +2 -1
- package/src/parser/api/parse.test.ts +7 -6
- package/src/parser/api/parse.ts +9 -8
- package/src/parser/autolink.test.ts +18 -18
- package/src/parser/block/blockquote.test.ts +79 -79
- package/src/parser/block/blockquote.ts +5 -5
- package/src/parser/block/codeblock.test.ts +57 -57
- package/src/parser/block/codeblock.ts +3 -3
- package/src/parser/block/dlist.test.ts +57 -57
- package/src/parser/block/dlist.ts +6 -6
- package/src/parser/block/extension/aside.test.ts +9 -9
- package/src/parser/block/extension/aside.ts +5 -5
- package/src/parser/block/extension/example.test.ts +19 -19
- package/src/parser/block/extension/example.ts +6 -6
- package/src/parser/block/extension/fig.test.ts +36 -36
- package/src/parser/block/extension/figbase.test.ts +16 -16
- package/src/parser/block/extension/figbase.ts +2 -2
- package/src/parser/block/extension/figure.test.ts +63 -63
- package/src/parser/block/extension/figure.ts +3 -3
- package/src/parser/block/extension/message.test.ts +14 -14
- package/src/parser/block/extension/message.ts +5 -5
- package/src/parser/block/extension/placeholder.test.ts +13 -13
- package/src/parser/block/extension/placeholder.ts +2 -2
- package/src/parser/block/extension/table.test.ts +76 -76
- package/src/parser/block/extension/table.ts +14 -14
- package/src/parser/block/extension.test.ts +24 -24
- package/src/parser/block/heading.test.ts +59 -59
- package/src/parser/block/heading.ts +7 -7
- package/src/parser/block/ilist.test.ts +8 -12
- package/src/parser/block/ilist.ts +6 -6
- package/src/parser/block/mathblock.test.ts +32 -32
- package/src/parser/block/mathblock.ts +3 -3
- package/src/parser/block/mediablock.ts +3 -3
- package/src/parser/block/olist.test.ts +103 -103
- package/src/parser/block/olist.ts +5 -5
- package/src/parser/block/pagebreak.test.ts +16 -16
- package/src/parser/block/pagebreak.ts +2 -2
- package/src/parser/block/paragraph.test.ts +58 -58
- package/src/parser/block/paragraph.ts +2 -2
- package/src/parser/block/reply/cite.test.ts +40 -40
- package/src/parser/block/reply/cite.ts +6 -6
- package/src/parser/block/reply/quote.test.ts +51 -51
- package/src/parser/block/reply/quote.ts +3 -3
- package/src/parser/block/reply.test.ts +20 -20
- package/src/parser/block/reply.ts +3 -3
- package/src/parser/block/sidefence.test.ts +48 -48
- package/src/parser/block/sidefence.ts +4 -4
- package/src/parser/block/table.test.ts +50 -50
- package/src/parser/block/table.ts +12 -12
- package/src/parser/block/ulist.test.ts +53 -53
- package/src/parser/block/ulist.ts +6 -6
- package/src/parser/block.ts +6 -4
- package/src/parser/context.ts +39 -0
- package/src/parser/header.test.ts +23 -23
- package/src/parser/header.ts +5 -5
- package/src/parser/inline/annotation.test.ts +43 -43
- package/src/parser/inline/annotation.ts +15 -5
- package/src/parser/inline/autolink/account.test.ts +33 -33
- package/src/parser/inline/autolink/account.ts +9 -9
- package/src/parser/inline/autolink/anchor.test.ts +22 -22
- package/src/parser/inline/autolink/anchor.ts +4 -4
- package/src/parser/inline/autolink/channel.test.ts +15 -15
- package/src/parser/inline/autolink/email.test.ts +37 -37
- package/src/parser/inline/autolink/email.ts +2 -2
- package/src/parser/inline/autolink/hashnum.test.ts +33 -33
- package/src/parser/inline/autolink/hashnum.ts +6 -5
- package/src/parser/inline/autolink/hashtag.test.ts +60 -60
- package/src/parser/inline/autolink/hashtag.ts +4 -4
- package/src/parser/inline/autolink/url.test.ts +75 -75
- package/src/parser/inline/autolink/url.ts +4 -4
- package/src/parser/inline/bracket.test.ts +70 -70
- package/src/parser/inline/bracket.ts +35 -32
- package/src/parser/inline/code.test.ts +31 -31
- package/src/parser/inline/code.ts +4 -4
- package/src/parser/inline/deletion.test.ts +28 -28
- package/src/parser/inline/deletion.ts +4 -4
- package/src/parser/inline/emphasis.test.ts +40 -40
- package/src/parser/inline/emphasis.ts +3 -3
- package/src/parser/inline/emstrong.test.ts +101 -101
- package/src/parser/inline/emstrong.ts +23 -23
- package/src/parser/inline/extension/index.test.ts +92 -92
- package/src/parser/inline/extension/index.ts +5 -5
- package/src/parser/inline/extension/indexee.ts +5 -5
- package/src/parser/inline/extension/indexer.test.ts +24 -24
- package/src/parser/inline/extension/indexer.ts +2 -2
- package/src/parser/inline/extension/label.test.ts +33 -33
- package/src/parser/inline/extension/label.ts +2 -2
- package/src/parser/inline/extension/placeholder.test.ts +43 -43
- package/src/parser/inline/extension/placeholder.ts +4 -4
- package/src/parser/inline/html.test.ts +108 -108
- package/src/parser/inline/html.ts +10 -10
- package/src/parser/inline/htmlentity.test.ts +38 -38
- package/src/parser/inline/htmlentity.ts +5 -5
- package/src/parser/inline/insertion.test.ts +28 -28
- package/src/parser/inline/insertion.ts +4 -4
- package/src/parser/inline/italic.test.ts +55 -55
- package/src/parser/inline/italic.ts +4 -4
- package/src/parser/inline/link.test.ts +186 -187
- package/src/parser/inline/link.ts +16 -17
- package/src/parser/inline/mark.test.ts +31 -31
- package/src/parser/inline/mark.ts +5 -5
- package/src/parser/inline/math.test.ts +132 -132
- package/src/parser/inline/math.ts +2 -2
- package/src/parser/inline/media.test.ts +91 -91
- package/src/parser/inline/media.ts +15 -15
- package/src/parser/inline/reference.test.ts +109 -109
- package/src/parser/inline/reference.ts +16 -55
- package/src/parser/inline/remark.test.ts +50 -50
- package/src/parser/inline/remark.ts +5 -5
- package/src/parser/inline/ruby.test.ts +45 -45
- package/src/parser/inline/ruby.ts +17 -17
- package/src/parser/inline/shortmedia.test.ts +10 -10
- package/src/parser/inline/strong.test.ts +37 -37
- package/src/parser/inline/strong.ts +3 -3
- package/src/parser/inline/template.test.ts +23 -23
- package/src/parser/inline/template.ts +5 -5
- package/src/parser/inline.test.ts +224 -223
- package/src/parser/segment.ts +2 -2
- package/src/parser/source/escapable.test.ts +24 -24
- package/src/parser/source/escapable.ts +8 -8
- package/src/parser/source/line.test.ts +18 -18
- package/src/parser/source/str.ts +2 -2
- package/src/parser/source/text.test.ts +85 -85
- package/src/parser/source/text.ts +5 -5
- package/src/parser/source/unescapable.test.ts +24 -24
- package/src/parser/source/unescapable.ts +5 -5
- package/src/parser/util.ts +10 -11
- package/src/parser/visibility.ts +8 -9
- package/src/util/quote.ts +2 -1
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
import { Parser, Result, List,
|
|
1
|
+
import { Parser, Result, List, Node, Context, failsafe } from '../../data/parser';
|
|
2
2
|
import { matcher, clear } from '../../../combinator';
|
|
3
3
|
|
|
4
4
|
export function surround<P extends Parser, S = string>(
|
|
5
|
-
opener: string | RegExp | Parser<S, Context<P>>, parser: IntermediateParser<P>, closer: string | RegExp | Parser<S, Context<P>>,
|
|
5
|
+
opener: string | RegExp | Parser<S, Parser.Context<P>>, parser: Parser.IntermediateParser<P>, closer: string | RegExp | Parser<S, Parser.Context<P>>,
|
|
6
6
|
optional?: false,
|
|
7
|
-
backtracks?: readonly
|
|
8
|
-
f?: (rss: [List<
|
|
9
|
-
g?: (rss: [List<
|
|
7
|
+
backtracks?: readonly number[],
|
|
8
|
+
f?: (rss: [List<Node<S>>, List<Node<Parser.SubNode<P>>>, List<Node<S>>], context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>,
|
|
9
|
+
g?: (rss: [List<Node<S>>, List<Node<Parser.SubNode<P>>> | undefined], context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>,
|
|
10
10
|
): P;
|
|
11
11
|
export function surround<P extends Parser, S = string>(
|
|
12
|
-
opener: string | RegExp | Parser<S, Context<P>>, parser: IntermediateParser<P>, closer: string | RegExp | Parser<S, Context<P>>,
|
|
12
|
+
opener: string | RegExp | Parser<S, Parser.Context<P>>, parser: Parser.IntermediateParser<P>, closer: string | RegExp | Parser<S, Parser.Context<P>>,
|
|
13
13
|
optional?: boolean,
|
|
14
|
-
backtracks?: readonly
|
|
15
|
-
f?: (rss: [List<
|
|
16
|
-
g?: (rss: [List<
|
|
14
|
+
backtracks?: readonly number[],
|
|
15
|
+
f?: (rss: [List<Node<S>>, List<Node<Parser.SubNode<P>>> | undefined, List<Node<S>>], context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>,
|
|
16
|
+
g?: (rss: [List<Node<S>>, List<Node<Parser.SubNode<P>>> | undefined], context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>,
|
|
17
17
|
): P;
|
|
18
18
|
export function surround<P extends Parser, S = string>(
|
|
19
|
-
opener: string | RegExp | Parser<S, Context<P>>, parser: P, closer: string | RegExp | Parser<S, Context<P>>,
|
|
19
|
+
opener: string | RegExp | Parser<S, Parser.Context<P>>, parser: P, closer: string | RegExp | Parser<S, Parser.Context<P>>,
|
|
20
20
|
optional?: false,
|
|
21
|
-
backtracks?: readonly
|
|
22
|
-
f?: (rss: [List<
|
|
23
|
-
g?: (rss: [List<
|
|
21
|
+
backtracks?: readonly number[],
|
|
22
|
+
f?: (rss: [List<Node<S>>, List<Node<Parser.Node<P>>>, List<Node<S>>], context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>,
|
|
23
|
+
g?: (rss: [List<Node<S>>, List<Node<Parser.Node<P>>> | undefined], context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>,
|
|
24
24
|
): P;
|
|
25
25
|
export function surround<P extends Parser, S = string>(
|
|
26
|
-
opener: string | RegExp | Parser<S, Context<P>>, parser: P, closer: string | RegExp | Parser<S, Context<P>>,
|
|
26
|
+
opener: string | RegExp | Parser<S, Parser.Context<P>>, parser: P, closer: string | RegExp | Parser<S, Parser.Context<P>>,
|
|
27
27
|
optional?: boolean,
|
|
28
|
-
backtracks?: readonly
|
|
29
|
-
f?: (rss: [List<
|
|
30
|
-
g?: (rss: [List<
|
|
28
|
+
backtracks?: readonly number[],
|
|
29
|
+
f?: (rss: [List<Node<S>>, List<Node<Parser.Node<P>>> | undefined, List<Node<S>>], context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>,
|
|
30
|
+
g?: (rss: [List<Node<S>>, List<Node<Parser.Node<P>>> | undefined], context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>,
|
|
31
31
|
): P;
|
|
32
32
|
export function surround<P extends Parser<string>, S = string>(
|
|
33
|
-
opener: string | RegExp | Parser<S, Context<P>>, parser: string | RegExp | P, closer: string | RegExp | Parser<S, Context<P>>,
|
|
33
|
+
opener: string | RegExp | Parser<S, Parser.Context<P>>, parser: string | RegExp | P, closer: string | RegExp | Parser<S, Parser.Context<P>>,
|
|
34
34
|
optional?: false,
|
|
35
|
-
backtracks?: readonly
|
|
36
|
-
f?: (rss: [List<
|
|
37
|
-
g?: (rss: [List<
|
|
35
|
+
backtracks?: readonly number[],
|
|
36
|
+
f?: (rss: [List<Node<S>>, List<Node<Parser.Node<P>>>, List<Node<S>>], context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>,
|
|
37
|
+
g?: (rss: [List<Node<S>>, List<Node<Parser.Node<P>>> | undefined], context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>,
|
|
38
38
|
): P;
|
|
39
39
|
export function surround<P extends Parser<string>, S = string>(
|
|
40
|
-
opener: string | RegExp | Parser<S, Context<P>>, parser: string | RegExp | P, closer: string | RegExp | Parser<S, Context<P>>,
|
|
40
|
+
opener: string | RegExp | Parser<S, Parser.Context<P>>, parser: string | RegExp | P, closer: string | RegExp | Parser<S, Parser.Context<P>>,
|
|
41
41
|
optional?: boolean,
|
|
42
|
-
backtracks?: readonly
|
|
43
|
-
f?: (rss: [List<
|
|
44
|
-
g?: (rss: [List<
|
|
42
|
+
backtracks?: readonly number[],
|
|
43
|
+
f?: (rss: [List<Node<S>>, List<Node<Parser.Node<P>>> | undefined, List<Node<S>>], context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>,
|
|
44
|
+
g?: (rss: [List<Node<S>>, List<Node<Parser.Node<P>>> | undefined], context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>,
|
|
45
45
|
): P;
|
|
46
46
|
export function surround<N>(
|
|
47
47
|
opener: string | RegExp | Parser<N>, parser: string | RegExp | Parser<N>, closer: string | RegExp | Parser<N>,
|
|
48
48
|
optional: boolean = false,
|
|
49
|
-
backtracks: readonly
|
|
50
|
-
f?: (rss: [List<
|
|
51
|
-
g?: (rss: [List<
|
|
49
|
+
backtracks: readonly number[] = [],
|
|
50
|
+
f?: (rss: [List<Node<N>>, List<Node<N>>, List<Node<N>>], context: Context) => Result<N>,
|
|
51
|
+
g?: (rss: [List<Node<N>>, List<Node<N>> | undefined], context: Context) => Result<N>,
|
|
52
52
|
): Parser<N> {
|
|
53
53
|
switch (typeof opener) {
|
|
54
54
|
case 'string':
|
|
@@ -68,7 +68,7 @@ export function surround<N>(
|
|
|
68
68
|
closer = clear(matcher(closer, true));
|
|
69
69
|
}
|
|
70
70
|
assert(closer);
|
|
71
|
-
const [rbs, wbs] = reduce(backtracks);
|
|
71
|
+
const [blen, rbs, wbs] = reduce(backtracks);
|
|
72
72
|
return failsafe(input => {
|
|
73
73
|
const { context } = input;
|
|
74
74
|
const { source, position } = context;
|
|
@@ -79,7 +79,7 @@ export function surround<N>(
|
|
|
79
79
|
if (!nodesO) {
|
|
80
80
|
return void revert(context, linebreak);
|
|
81
81
|
}
|
|
82
|
-
if (rbs && isBacktrack(context, rbs, position,
|
|
82
|
+
if (rbs && isBacktrack(context, rbs, position, blen)) {
|
|
83
83
|
return void revert(context, linebreak);
|
|
84
84
|
}
|
|
85
85
|
const nodesM = context.position < source.length ? parser(input) : undefined;
|
|
@@ -110,98 +110,98 @@ export function surround<N>(
|
|
|
110
110
|
});
|
|
111
111
|
}
|
|
112
112
|
export function open<P extends Parser>(
|
|
113
|
-
opener: string | RegExp | Parser<Node<P>, Context<P>>,
|
|
113
|
+
opener: string | RegExp | Parser<Parser.Node<P>, Parser.Context<P>>,
|
|
114
114
|
parser: P,
|
|
115
115
|
optional?: boolean,
|
|
116
|
-
backtracks?: readonly
|
|
116
|
+
backtracks?: readonly number[],
|
|
117
117
|
): P;
|
|
118
118
|
export function open<P extends Parser<string>>(
|
|
119
|
-
opener: string | RegExp | Parser<Node<P>, Context<P>>,
|
|
119
|
+
opener: string | RegExp | Parser<Parser.Node<P>, Parser.Context<P>>,
|
|
120
120
|
parser: string | RegExp | P,
|
|
121
121
|
optional?: boolean,
|
|
122
|
-
backtracks?: readonly
|
|
122
|
+
backtracks?: readonly number[],
|
|
123
123
|
): P;
|
|
124
124
|
export function open<N>(
|
|
125
|
-
opener: string | RegExp | Parser<N,
|
|
125
|
+
opener: string | RegExp | Parser<N, Context>,
|
|
126
126
|
parser: string | RegExp | Parser<N>,
|
|
127
127
|
optional?: boolean,
|
|
128
|
-
backtracks
|
|
128
|
+
backtracks: readonly number[] = [],
|
|
129
129
|
): Parser<N> {
|
|
130
130
|
return surround(opener, parser as Parser<N>, '', optional, backtracks);
|
|
131
131
|
}
|
|
132
132
|
export function close<P extends Parser>(
|
|
133
133
|
parser: P,
|
|
134
|
-
closer: string | RegExp | Parser<Node<P>, Context<P>>,
|
|
134
|
+
closer: string | RegExp | Parser<Parser.Node<P>, Parser.Context<P>>,
|
|
135
135
|
optional?: boolean,
|
|
136
|
-
backtracks?: readonly
|
|
136
|
+
backtracks?: readonly number[],
|
|
137
137
|
): P;
|
|
138
138
|
export function close<P extends Parser<string>>(
|
|
139
139
|
parser: string | RegExp | P,
|
|
140
|
-
closer: string | RegExp | Parser<Node<P>, Context<P>>,
|
|
140
|
+
closer: string | RegExp | Parser<Parser.Node<P>, Parser.Context<P>>,
|
|
141
141
|
optional?: boolean,
|
|
142
|
-
backtracks?: readonly
|
|
142
|
+
backtracks?: readonly number[],
|
|
143
143
|
): P;
|
|
144
144
|
export function close<N>(
|
|
145
145
|
parser: string | RegExp | Parser<N>,
|
|
146
|
-
closer: string | RegExp | Parser<N,
|
|
146
|
+
closer: string | RegExp | Parser<N, Context>,
|
|
147
147
|
optional?: boolean,
|
|
148
|
-
backtracks
|
|
148
|
+
backtracks: readonly number[] = [],
|
|
149
149
|
): Parser<N> {
|
|
150
150
|
return surround('', parser as Parser<N>, closer, optional, backtracks);
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
const commandsize = 2;
|
|
154
154
|
export function isBacktrack(
|
|
155
|
-
context:
|
|
155
|
+
context: Context,
|
|
156
156
|
backtrack: number,
|
|
157
157
|
position: number = context.position,
|
|
158
158
|
length: number = 1,
|
|
159
159
|
): boolean {
|
|
160
|
-
assert(
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
const { backtracks = {}, offset = 0 } = context;
|
|
160
|
+
assert(1 & backtrack);
|
|
161
|
+
assert(backtrack >>> commandsize);
|
|
162
|
+
assert(0 < length && length < 3);
|
|
163
|
+
const { backtracks, offset } = context;
|
|
165
164
|
for (let i = 0; i < length; ++i) {
|
|
166
|
-
if (position + i
|
|
167
|
-
if (i > 0 && source[position + i] !== source[position]) break;
|
|
168
|
-
const pos = position + i + offset;
|
|
169
|
-
if (backtracks[pos] & backtrack >>> commandsize) return true;
|
|
165
|
+
if (backtracks[position + i + offset] & backtrack >>> commandsize) return true;
|
|
170
166
|
}
|
|
171
167
|
return false;
|
|
172
168
|
}
|
|
173
169
|
export function setBacktrack(
|
|
174
|
-
context:
|
|
170
|
+
context: Context,
|
|
175
171
|
backtrack: number,
|
|
176
172
|
position: number,
|
|
177
173
|
length: number = 1,
|
|
178
174
|
): void {
|
|
179
175
|
// バックトラックの可能性がなく記録不要の場合もあるが判別が面倒なので省略
|
|
180
|
-
assert(
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
const { backtracks = {}, offset = 0 } = context;
|
|
176
|
+
assert(2 & backtrack);
|
|
177
|
+
assert(backtrack >>> commandsize);
|
|
178
|
+
assert(0 < length && length < 3);
|
|
179
|
+
const { backtracks, offset } = context;
|
|
185
180
|
for (let i = 0; i < length; ++i) {
|
|
186
|
-
|
|
187
|
-
const pos = position + i + offset;
|
|
188
|
-
backtracks[pos] |= backtrack >>> commandsize;
|
|
181
|
+
backtracks[position + i + offset] |= backtrack >>> commandsize;
|
|
189
182
|
}
|
|
190
183
|
}
|
|
191
|
-
function reduce(backtracks: readonly number[]): readonly [number, number] {
|
|
184
|
+
function reduce(backtracks: readonly number[]): readonly [number, number, number] {
|
|
185
|
+
let len = 1;
|
|
192
186
|
let rbs = 0;
|
|
193
187
|
let wbs = 0;
|
|
194
188
|
for (const backtrack of backtracks) {
|
|
195
|
-
if (backtrack
|
|
189
|
+
if (backtrack >>> commandsize === 0) {
|
|
190
|
+
len = backtrack;
|
|
191
|
+
assert(len > 0);
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
assert(backtrack >>> commandsize);
|
|
195
|
+
if (1 & backtrack) {
|
|
196
196
|
rbs |= backtrack;
|
|
197
197
|
}
|
|
198
|
-
if (
|
|
198
|
+
if (2 & backtrack) {
|
|
199
199
|
wbs |= backtrack;
|
|
200
200
|
}
|
|
201
201
|
}
|
|
202
|
-
return [rbs, wbs];
|
|
202
|
+
return [len, rbs, wbs];
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
-
function revert(context:
|
|
205
|
+
function revert(context: Context, linebreak: number): void {
|
|
206
206
|
context.linebreak = linebreak;
|
|
207
207
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Parser, Result, List,
|
|
1
|
+
import { Parser, Result, List, Node, Context, failsafe } from '../../data/parser';
|
|
2
2
|
|
|
3
|
-
export function bind<P extends Parser>(parser: IntermediateParser<P>, f: (nodes: List<
|
|
4
|
-
export function bind<P extends Parser>(parser: P, f: (nodes: List<
|
|
5
|
-
export function bind<N, P extends Parser>(parser: Parser<N, Context<P>, SubParsers<P>>, f: (nodes: List<
|
|
6
|
-
export function bind<U, P extends Parser>(parser: P, f: (nodes: List<
|
|
7
|
-
export function bind<N, U>(parser: Parser<N>, f: (nodes: List<
|
|
3
|
+
export function bind<P extends Parser>(parser: Parser.IntermediateParser<P>, f: (nodes: List<Node<Parser.SubNode<P>>>, context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>): P;
|
|
4
|
+
export function bind<P extends Parser>(parser: P, f: (nodes: List<Node<Parser.Node<P>>>, context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>): P;
|
|
5
|
+
export function bind<N, P extends Parser>(parser: Parser<N, Parser.Context<P>, Parser.SubParsers<P>>, f: (nodes: List<Node<N>>, context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>): P;
|
|
6
|
+
export function bind<U, P extends Parser>(parser: P, f: (nodes: List<Node<Parser.Node<P>>>, context: Parser.Context<P>) => Result<U, Parser.Context<P>, Parser.SubParsers<P>>): Parser<U, Parser.Context<P>, Parser.SubParsers<P>>;
|
|
7
|
+
export function bind<N, U>(parser: Parser<N>, f: (nodes: List<Node<N>>, context: Context) => Result<U>): Parser<U> {
|
|
8
8
|
assert(parser);
|
|
9
9
|
return failsafe(input => {
|
|
10
10
|
const { context } = input;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Parser, List,
|
|
1
|
+
import { Parser, List, Node, Context } from '../../data/parser';
|
|
2
2
|
import { bind } from './bind';
|
|
3
3
|
|
|
4
|
-
export function fmap<P extends Parser>(parser: IntermediateParser<P>, f: (nodes: List<
|
|
5
|
-
export function fmap<P extends Parser>(parser: P, f: (nodes: List<
|
|
6
|
-
export function fmap<N, P extends Parser>(parser: Parser<N, Context<P>, SubParsers<P>>, f: (nodes: List<
|
|
7
|
-
export function fmap<U, P extends Parser>(parser: P, f: (nodes: List<
|
|
8
|
-
export function fmap<N, U>(parser: Parser<N>, f: (nodes: List<
|
|
4
|
+
export function fmap<P extends Parser>(parser: Parser.IntermediateParser<P>, f: (nodes: List<Node<Parser.SubNode<P>>>, context: Parser.Context<P>) => List<Node<Parser.Node<P>>>): P;
|
|
5
|
+
export function fmap<P extends Parser>(parser: P, f: (nodes: List<Node<Parser.Node<P>>>, context: Parser.Context<P>) => List<Node<Parser.Node<P>>>): P;
|
|
6
|
+
export function fmap<N, P extends Parser>(parser: Parser<N, Parser.Context<P>, Parser.SubParsers<P>>, f: (nodes: List<Node<N>>, context: Parser.Context<P>) => List<Node<Parser.Node<P>>>): P;
|
|
7
|
+
export function fmap<U, P extends Parser>(parser: P, f: (nodes: List<Node<Parser.Node<P>>>, context: Parser.Context<P>) => List<Node<U>>): Parser<U, Parser.Context<P>, Parser.SubParsers<P>>;
|
|
8
|
+
export function fmap<N, U>(parser: Parser<N>, f: (nodes: List<Node<N>>, context: Context) => List<Node<U>>): Parser<U> {
|
|
9
9
|
return bind(parser, (nodes, context) => f(nodes, context));
|
|
10
10
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Parser,
|
|
1
|
+
import { Parser, Context } from './parser';
|
|
2
2
|
|
|
3
|
-
export class List<N extends List.Node = List.Node, C extends
|
|
3
|
+
export class List<N extends List.Node = List.Node, C extends Context = Context, D extends Parser<unknown, C>[] = any> {
|
|
4
4
|
constructor(nodes?: ArrayLike<N>) {
|
|
5
5
|
if (nodes === undefined) return;
|
|
6
6
|
for (let i = 0; i < nodes.length; ++i) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Input,
|
|
2
|
-
import { matcher } from '
|
|
1
|
+
import { Input, Context } from './parser';
|
|
2
|
+
import { matcher } from '../../combinator';
|
|
3
3
|
|
|
4
4
|
interface Delimiter {
|
|
5
5
|
readonly memory: Delimiter[];
|
|
@@ -27,7 +27,7 @@ export class Delimiters {
|
|
|
27
27
|
return `r/${pattern.source}`;
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
-
public static matcher(pattern: string | RegExp | undefined): (input: Input<
|
|
30
|
+
public static matcher(pattern: string | RegExp | undefined): (input: Input<Context>) => true | undefined {
|
|
31
31
|
switch (typeof pattern) {
|
|
32
32
|
case 'undefined':
|
|
33
33
|
return () => undefined;
|
|
@@ -130,7 +130,7 @@ export class Delimiters {
|
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
public match(input: Input): boolean {
|
|
133
|
-
const { precedence
|
|
133
|
+
const { precedence } = input.context;
|
|
134
134
|
const { delimiters } = this;
|
|
135
135
|
for (let i = delimiters.length; i--;) {
|
|
136
136
|
const delimiter = delimiters[i];
|
|
@@ -1,23 +1,24 @@
|
|
|
1
|
-
import { Parser, List,
|
|
1
|
+
import { Parser, List, Node, Context, input } from '../parser';
|
|
2
2
|
import { some } from './some';
|
|
3
3
|
import { reset, context, creation } from './context';
|
|
4
4
|
import { unwrap } from '../../../parser/util';
|
|
5
5
|
|
|
6
6
|
describe('Unit: combinator/data/parser/context', () => {
|
|
7
|
-
interface
|
|
7
|
+
interface Ctx extends Context {
|
|
8
8
|
status?: boolean;
|
|
9
9
|
}
|
|
10
|
+
type Opts = Partial<Ctx>;
|
|
10
11
|
|
|
11
12
|
describe('reset', () => {
|
|
12
13
|
const parser: Parser<number> = some(creation(1,
|
|
13
14
|
({ context }) => {
|
|
14
15
|
context.position += 1;
|
|
15
|
-
return new List([new
|
|
16
|
+
return new List([new Node(context.resources?.clock ?? NaN)]);
|
|
16
17
|
}));
|
|
17
18
|
|
|
18
19
|
it('root', () => {
|
|
19
|
-
const base:
|
|
20
|
-
const ctx:
|
|
20
|
+
const base: Opts = { resources: { clock: 3, recursions: [1] } };
|
|
21
|
+
const ctx: Ctx = new Context();
|
|
21
22
|
assert.deepStrictEqual([...unwrap(reset(base, parser)(input('123', ctx))!)], [3, 2, 1]);
|
|
22
23
|
assert(base.resources?.clock === 3);
|
|
23
24
|
assert(ctx.resources?.clock === undefined);
|
|
@@ -26,8 +27,8 @@ describe('Unit: combinator/data/parser/context', () => {
|
|
|
26
27
|
});
|
|
27
28
|
|
|
28
29
|
it('node', () => {
|
|
29
|
-
const base:
|
|
30
|
-
const ctx:
|
|
30
|
+
const base: Opts = { resources: { clock: 3, recursions: [1] } };
|
|
31
|
+
const ctx: Ctx = new Context({ resources: { clock: 2, recursions: [1] } });
|
|
31
32
|
assert.deepStrictEqual([...unwrap(reset(base, parser)(input('1', ctx))!)], [2]);
|
|
32
33
|
assert(base.resources?.clock === 3);
|
|
33
34
|
assert(ctx.resources?.clock === 1);
|
|
@@ -38,15 +39,15 @@ describe('Unit: combinator/data/parser/context', () => {
|
|
|
38
39
|
});
|
|
39
40
|
|
|
40
41
|
describe('context', () => {
|
|
41
|
-
const parser: Parser<boolean,
|
|
42
|
+
const parser: Parser<boolean, Ctx & Ctx> = some(creation(1,
|
|
42
43
|
({ context }) => {
|
|
43
44
|
context.position += 1;
|
|
44
|
-
return new List([new
|
|
45
|
+
return new List([new Node(context.status!)]);
|
|
45
46
|
}));
|
|
46
47
|
|
|
47
48
|
it('', () => {
|
|
48
|
-
const base:
|
|
49
|
-
const ctx:
|
|
49
|
+
const base: Opts = { status: true };
|
|
50
|
+
const ctx: Ctx = new Context({ resources: { clock: 2, recursions: [1] } });
|
|
50
51
|
assert.deepStrictEqual([...unwrap(context(base, parser)(input('1', ctx))!)], [true]);
|
|
51
52
|
assert(base.resources?.clock === undefined);
|
|
52
53
|
assert(ctx.resources?.clock === 1);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { Parser, Result, List, Node, Context, Options } from '../../data/parser';
|
|
1
2
|
import { min } from 'spica/alias';
|
|
2
|
-
import { Parser, Result, List, Data, Ctx, CtxOptions, Node, Context } from '../../data/parser';
|
|
3
3
|
import { clone } from 'spica/assign';
|
|
4
4
|
|
|
5
|
-
export function reset<P extends Parser>(base:
|
|
6
|
-
export function reset<N>(base:
|
|
5
|
+
export function reset<P extends Parser>(base: Options, parser: P): P;
|
|
6
|
+
export function reset<N>(base: Context, parser: Parser<N>): Parser<N> {
|
|
7
7
|
assert(Object.getPrototypeOf(base) === Object.prototype);
|
|
8
8
|
assert(Object.freeze(base));
|
|
9
9
|
const changes = Object.entries(base);
|
|
@@ -13,8 +13,8 @@ export function reset<N>(base: Ctx, parser: Parser<N>): Parser<N> {
|
|
|
13
13
|
apply(parser, { ...context }, changes, values, true);
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
export function context<P extends Parser>(base:
|
|
17
|
-
export function context<N>(base:
|
|
16
|
+
export function context<P extends Parser>(base: Options, parser: P): P;
|
|
17
|
+
export function context<N>(base: Context, parser: Parser<N>): Parser<N> {
|
|
18
18
|
assert(Object.getPrototypeOf(base) === Object.prototype);
|
|
19
19
|
assert(Object.freeze(base));
|
|
20
20
|
const changes = Object.entries(base);
|
|
@@ -23,8 +23,8 @@ export function context<N>(base: Ctx, parser: Parser<N>): Parser<N> {
|
|
|
23
23
|
apply(parser, context, changes, values);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
function apply<P extends Parser>(parser: P, context: Context<P>, changes: readonly [string, unknown][], values: unknown[], reset?: boolean): Result<Node<P>>;
|
|
27
|
-
function apply<N>(parser: Parser<N>, context:
|
|
26
|
+
function apply<P extends Parser>(parser: P, context: Parser.Context<P>, changes: readonly [string, unknown][], values: unknown[], reset?: boolean): Result<Parser.Node<P>>;
|
|
27
|
+
function apply<N>(parser: Parser<N>, context: Context, changes: readonly [string, unknown][], values: unknown[], reset = false): Result<N> {
|
|
28
28
|
for (let i = 0; i < changes.length; ++i) {
|
|
29
29
|
const change = changes[i];
|
|
30
30
|
const prop = change[0];
|
|
@@ -36,7 +36,6 @@ function apply<N>(parser: Parser<N>, context: Ctx, changes: readonly [string, un
|
|
|
36
36
|
assert(reset);
|
|
37
37
|
assert(!context.offset);
|
|
38
38
|
assert(!context.precedence);
|
|
39
|
-
assert(!context.delimiters);
|
|
40
39
|
assert(!context.state);
|
|
41
40
|
values[i] = context[prop];
|
|
42
41
|
context[prop as string] ??= clone({}, change[1] as object);
|
|
@@ -78,7 +77,7 @@ export function creation(cost: number, parser: Parser): Parser {
|
|
|
78
77
|
return result;
|
|
79
78
|
};
|
|
80
79
|
}
|
|
81
|
-
export function consume(cost: number, context:
|
|
80
|
+
export function consume(cost: number, context: Context): void {
|
|
82
81
|
const { resources } = context;
|
|
83
82
|
if (!resources) return;
|
|
84
83
|
if (resources.clock < cost) throw new Error('Too many creations');
|
|
@@ -107,7 +106,7 @@ export function precedence<N>(precedence: number, parser: Parser<N>): Parser<N>
|
|
|
107
106
|
assert(precedence >= 0);
|
|
108
107
|
return input => {
|
|
109
108
|
const { context } = input;
|
|
110
|
-
const { delimiters, precedence: p
|
|
109
|
+
const { delimiters, precedence: p } = context;
|
|
111
110
|
const shift = delimiters && precedence > p;
|
|
112
111
|
context.precedence = precedence;
|
|
113
112
|
// デリミタはシフト後に設定しなければならない
|
|
@@ -152,8 +151,8 @@ export function constraint<N>(state: number, positive: boolean | Parser<N>, pars
|
|
|
152
151
|
return input => {
|
|
153
152
|
const { context } = input;
|
|
154
153
|
const s = positive
|
|
155
|
-
? state & context.state
|
|
156
|
-
: state & ~context.state
|
|
154
|
+
? state & context.state
|
|
155
|
+
: state & ~context.state;
|
|
157
156
|
return s === state
|
|
158
157
|
? parser(input)
|
|
159
158
|
: undefined;
|
|
@@ -173,7 +172,7 @@ export function matcher(pattern: string | RegExp, advance: boolean): Parser<stri
|
|
|
173
172
|
if (advance) {
|
|
174
173
|
context.position += pattern.length;
|
|
175
174
|
}
|
|
176
|
-
return new List([new
|
|
175
|
+
return new List([new Node(pattern)]);
|
|
177
176
|
};
|
|
178
177
|
case 'object':
|
|
179
178
|
assert(pattern.sticky);
|
|
@@ -186,7 +185,7 @@ export function matcher(pattern: string | RegExp, advance: boolean): Parser<stri
|
|
|
186
185
|
if (advance) {
|
|
187
186
|
context.position += src.length;
|
|
188
187
|
}
|
|
189
|
-
return new List([new
|
|
188
|
+
return new List([new Node(src)]);
|
|
190
189
|
};
|
|
191
190
|
}
|
|
192
191
|
}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { Parser, List,
|
|
1
|
+
import { Parser, List, Node, Context } from '../parser';
|
|
2
2
|
|
|
3
|
-
export function inits<P extends Parser>(parsers: SubParsers<P>, resume?: (nodes: List<
|
|
4
|
-
export function inits<N, D extends Parser<N>[]>(parsers: D, resume?: (nodes: List<
|
|
3
|
+
export function inits<P extends Parser>(parsers: Parser.SubParsers<P>, resume?: (nodes: List<Node<Parser.SubNode<P>>>) => boolean): Parser.SubNode<P> extends Parser.Node<P> ? P : Parser<Parser.SubNode<P>, Parser.Context<P>, Parser.SubParsers<P>>;
|
|
4
|
+
export function inits<N, D extends Parser<N>[]>(parsers: D, resume?: (nodes: List<Node<N>>) => boolean): Parser<N, Context, D> {
|
|
5
5
|
assert(parsers.every(f => f));
|
|
6
6
|
if (parsers.length === 1) return parsers[0];
|
|
7
7
|
return input => {
|
|
8
8
|
const { context } = input;
|
|
9
9
|
const { source } = context;
|
|
10
|
-
let nodes: List<
|
|
10
|
+
let nodes: List<Node<N>> | undefined;
|
|
11
11
|
for (let len = parsers.length, i = 0; i < len; ++i) {
|
|
12
12
|
if (context.position === source.length) break;
|
|
13
|
-
if (context.delimiters
|
|
13
|
+
if (context.delimiters.match(input)) break;
|
|
14
14
|
const result = parsers[i](input);
|
|
15
15
|
if (result === undefined) break;
|
|
16
16
|
nodes = nodes?.import(result) ?? result;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Parser, List,
|
|
1
|
+
import { Parser, List, Node, Context, input } from '../parser';
|
|
2
2
|
import { sequence } from './sequence';
|
|
3
3
|
import { inspect } from '../../../debug.test';
|
|
4
4
|
|
|
@@ -6,27 +6,26 @@ describe('Unit: combinator/data/parser/sequence', () => {
|
|
|
6
6
|
describe('sequence', () => {
|
|
7
7
|
const a: Parser<string> = ({ context }) => {
|
|
8
8
|
return context.source[context.position] === 'a'
|
|
9
|
-
? void ++context.position || new List([new
|
|
9
|
+
? void ++context.position || new List([new Node('A')])
|
|
10
10
|
: undefined;
|
|
11
11
|
};
|
|
12
12
|
const b: Parser<string> = ({ context }) => {
|
|
13
13
|
return context.source[context.position] === 'b'
|
|
14
|
-
? void ++context.position || new List([new
|
|
14
|
+
? void ++context.position || new List([new Node('B')])
|
|
15
15
|
: undefined;
|
|
16
16
|
};
|
|
17
|
-
const ab = sequence<Parser<string,
|
|
18
|
-
const { context: ctx } = input('', {});
|
|
17
|
+
const ab = sequence<Parser<string, Context, [typeof a, typeof b]>>([a, b]);
|
|
19
18
|
|
|
20
19
|
it('basic', () => {
|
|
21
20
|
const parser = ab;
|
|
22
|
-
assert.deepStrictEqual(inspect(parser
|
|
23
|
-
assert.deepStrictEqual(inspect(parser
|
|
24
|
-
assert.deepStrictEqual(inspect(parser
|
|
25
|
-
assert.deepStrictEqual(inspect(parser
|
|
26
|
-
assert.deepStrictEqual(inspect(parser
|
|
27
|
-
assert.deepStrictEqual(inspect(parser
|
|
28
|
-
assert.deepStrictEqual(inspect(parser
|
|
29
|
-
assert.deepStrictEqual(inspect(parser
|
|
21
|
+
assert.deepStrictEqual(inspect(parser, input('', new Context())), undefined);
|
|
22
|
+
assert.deepStrictEqual(inspect(parser, input('a', new Context())), undefined);
|
|
23
|
+
assert.deepStrictEqual(inspect(parser, input('b', new Context())), undefined);
|
|
24
|
+
assert.deepStrictEqual(inspect(parser, input('ab', new Context())), [['A', 'B'], '']);
|
|
25
|
+
assert.deepStrictEqual(inspect(parser, input('ba', new Context())), undefined);
|
|
26
|
+
assert.deepStrictEqual(inspect(parser, input('aab', new Context())), undefined);
|
|
27
|
+
assert.deepStrictEqual(inspect(parser, input('abb', new Context())), [['A', 'B'], 'b']);
|
|
28
|
+
assert.deepStrictEqual(inspect(parser, input('bba', new Context())), undefined);
|
|
30
29
|
});
|
|
31
30
|
|
|
32
31
|
});
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { Parser, List,
|
|
1
|
+
import { Parser, List, Node, Context } from '../parser';
|
|
2
2
|
|
|
3
|
-
export function sequence<P extends Parser>(parsers: SubParsers<P>, resume?: (nodes: List<
|
|
4
|
-
export function sequence<N, D extends Parser<N>[]>(parsers: D, resume?: (nodes: List<
|
|
3
|
+
export function sequence<P extends Parser>(parsers: Parser.SubParsers<P>, resume?: (nodes: List<Node<Parser.SubNode<P>>>) => boolean): Parser.SubNode<P> extends Parser.Node<P> ? P : Parser<Parser.SubNode<P>, Parser.Context<P>, Parser.SubParsers<P>>;
|
|
4
|
+
export function sequence<N, D extends Parser<N>[]>(parsers: D, resume?: (nodes: List<Node<N>>) => boolean): Parser<N, Context, D> {
|
|
5
5
|
assert(parsers.every(f => f));
|
|
6
6
|
if (parsers.length === 1) return parsers[0];
|
|
7
7
|
return input => {
|
|
8
8
|
const { context } = input;
|
|
9
9
|
const { source } = context;
|
|
10
|
-
let nodes: List<
|
|
10
|
+
let nodes: List<Node<N>> | undefined;
|
|
11
11
|
for (let len = parsers.length, i = 0; i < len; ++i) {
|
|
12
12
|
if (context.position === source.length) return;
|
|
13
|
-
if (context.delimiters
|
|
13
|
+
if (context.delimiters.match(input)) return;
|
|
14
14
|
const result = parsers[i](input);
|
|
15
15
|
if (result === undefined) return;
|
|
16
16
|
nodes = nodes?.import(result) ?? result;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Parser, List,
|
|
1
|
+
import { Parser, List, Node, Context, input } from '../parser';
|
|
2
2
|
import { union } from './union';
|
|
3
3
|
import { some } from './some';
|
|
4
4
|
import { inspect } from '../../../debug.test';
|
|
@@ -7,30 +7,29 @@ describe('Unit: combinator/data/parser/some', () => {
|
|
|
7
7
|
describe('some', () => {
|
|
8
8
|
const a: Parser<string> = ({ context }) => {
|
|
9
9
|
return context.source[context.position] === 'a'
|
|
10
|
-
? void ++context.position || new List([new
|
|
10
|
+
? void ++context.position || new List([new Node('A')])
|
|
11
11
|
: undefined;
|
|
12
12
|
};
|
|
13
13
|
const b: Parser<string> = ({ context }) => {
|
|
14
14
|
return context.source[context.position] === 'b'
|
|
15
|
-
? void ++context.position || new List([new
|
|
15
|
+
? void ++context.position || new List([new Node('B')])
|
|
16
16
|
: undefined;
|
|
17
17
|
};
|
|
18
|
-
const ab = union<Parser<string,
|
|
19
|
-
const { context: ctx } = input('', {});
|
|
18
|
+
const ab = union<Parser<string, Context, [typeof a, typeof b]>>([a, b]);
|
|
20
19
|
|
|
21
20
|
it('basic', () => {
|
|
22
21
|
const parser = some(ab, /aaa/y);
|
|
23
|
-
assert.deepStrictEqual(inspect(parser
|
|
24
|
-
assert.deepStrictEqual(inspect(parser
|
|
25
|
-
assert.deepStrictEqual(inspect(parser
|
|
26
|
-
assert.deepStrictEqual(inspect(parser
|
|
27
|
-
assert.deepStrictEqual(inspect(parser
|
|
28
|
-
assert.deepStrictEqual(inspect(parser
|
|
29
|
-
assert.deepStrictEqual(inspect(parser
|
|
30
|
-
assert.deepStrictEqual(inspect(parser
|
|
31
|
-
assert.deepStrictEqual(inspect(parser
|
|
32
|
-
assert.deepStrictEqual(inspect(parser
|
|
33
|
-
assert.deepStrictEqual(inspect(parser
|
|
22
|
+
assert.deepStrictEqual(inspect(parser, input('', new Context())), undefined);
|
|
23
|
+
assert.deepStrictEqual(inspect(parser, input('a', new Context())), [['A'], '']);
|
|
24
|
+
assert.deepStrictEqual(inspect(parser, input('b', new Context())), [['B'], '']);
|
|
25
|
+
assert.deepStrictEqual(inspect(parser, input('ab', new Context())), [['A', 'B'], '']);
|
|
26
|
+
assert.deepStrictEqual(inspect(parser, input('ba', new Context())), [['B', 'A'], '']);
|
|
27
|
+
assert.deepStrictEqual(inspect(parser, input('aab', new Context())), [['A', 'A', 'B'], '']);
|
|
28
|
+
assert.deepStrictEqual(inspect(parser, input('bba', new Context())), [['B', 'B', 'A'], '']);
|
|
29
|
+
assert.deepStrictEqual(inspect(parser, input('aaa', new Context())), undefined);
|
|
30
|
+
assert.deepStrictEqual(inspect(parser, input('bbb', new Context())), [['B', 'B', 'B'], '']);
|
|
31
|
+
assert.deepStrictEqual(inspect(parser, input('aaab', new Context())), undefined);
|
|
32
|
+
assert.deepStrictEqual(inspect(parser, input('baaa', new Context())), [['B'], 'aaa']);
|
|
34
33
|
});
|
|
35
34
|
|
|
36
35
|
});
|