securemark 0.295.1 → 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 +4 -0
- package/design.md +4 -3
- package/dist/index.js +514 -459
- 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 +32 -32
- 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 +14 -4
- 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 +15 -54
- 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,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
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Parser, List,
|
|
2
|
-
import { Delimiters } from '
|
|
1
|
+
import { Parser, List, Node } from '../parser';
|
|
2
|
+
import { Delimiters } from '../delimiter';
|
|
3
3
|
|
|
4
4
|
type DelimiterOption = readonly [delimiter: string | RegExp, precedence: number];
|
|
5
5
|
|
|
@@ -18,22 +18,21 @@ export function some<N>(parser: Parser<N>, end?: string | RegExp | number, delim
|
|
|
18
18
|
const { context } = input;
|
|
19
19
|
const { source, position } = context;
|
|
20
20
|
//assert(context.backtracks ??= {});
|
|
21
|
-
let nodes: List<
|
|
21
|
+
let nodes: List<Node<N>> | undefined;
|
|
22
22
|
if (delims.length > 0) {
|
|
23
|
-
context.delimiters ??= new Delimiters();
|
|
24
23
|
context.delimiters.push(delims);
|
|
25
24
|
}
|
|
26
25
|
// whileは数倍遅い
|
|
27
26
|
for (const len = source.length; context.position < len;) {
|
|
28
27
|
if (match(input)) break;
|
|
29
|
-
if (context.delimiters
|
|
28
|
+
if (context.delimiters.match(input)) break;
|
|
30
29
|
const result = parser(input);
|
|
31
30
|
if (result === undefined) break;
|
|
32
31
|
nodes = nodes?.import(result) ?? result;
|
|
33
32
|
if (limit >= 0 && context.position - position > limit) break;
|
|
34
33
|
}
|
|
35
34
|
if (delims.length > 0) {
|
|
36
|
-
context.delimiters
|
|
35
|
+
context.delimiters.pop(delims.length);
|
|
37
36
|
}
|
|
38
37
|
assert(context.position >= position);
|
|
39
38
|
return context.position > position
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Parser, List,
|
|
1
|
+
import { Parser, List, Node, Context, input } from '../parser';
|
|
2
2
|
import { subsequence } from './subsequence';
|
|
3
3
|
import { inspect } from '../../../debug.test';
|
|
4
4
|
|
|
@@ -6,35 +6,34 @@ describe('Unit: combinator/data/parser/subsequence', () => {
|
|
|
6
6
|
describe('subsequence', () => {
|
|
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
17
|
const c: Parser<string> = ({ context }) => {
|
|
18
18
|
return context.source[context.position] === 'c'
|
|
19
|
-
? void ++context.position || new List([new
|
|
19
|
+
? void ++context.position || new List([new Node('C')])
|
|
20
20
|
: undefined;
|
|
21
21
|
};
|
|
22
|
-
const abc = subsequence<Parser<string,
|
|
23
|
-
const { context: ctx } = input('', {});
|
|
22
|
+
const abc = subsequence<Parser<string, Context, [typeof a, typeof b, typeof c]>>([a, b, c]);
|
|
24
23
|
|
|
25
24
|
it('basic', () => {
|
|
26
25
|
const parser = abc;
|
|
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
|
|
34
|
-
assert.deepStrictEqual(inspect(parser
|
|
35
|
-
assert.deepStrictEqual(inspect(parser
|
|
36
|
-
assert.deepStrictEqual(inspect(parser
|
|
37
|
-
assert.deepStrictEqual(inspect(parser
|
|
26
|
+
assert.deepStrictEqual(inspect(parser, input('', new Context())), undefined);
|
|
27
|
+
assert.deepStrictEqual(inspect(parser, input('a', new Context())), [['A'], '']);
|
|
28
|
+
assert.deepStrictEqual(inspect(parser, input('b', new Context())), [['B'], '']);
|
|
29
|
+
assert.deepStrictEqual(inspect(parser, input('c', new Context())), [['C'], '']);
|
|
30
|
+
assert.deepStrictEqual(inspect(parser, input('ab', new Context())), [['A', 'B'], '']);
|
|
31
|
+
assert.deepStrictEqual(inspect(parser, input('ba', new Context())), [['B'], 'a']);
|
|
32
|
+
assert.deepStrictEqual(inspect(parser, input('aab', new Context())), [['A'], 'ab']);
|
|
33
|
+
assert.deepStrictEqual(inspect(parser, input('abb', new Context())), [['A', 'B'], 'b']);
|
|
34
|
+
assert.deepStrictEqual(inspect(parser, input('bba', new Context())), [['B'], 'ba']);
|
|
35
|
+
assert.deepStrictEqual(inspect(parser, input('ac', new Context())), [['A', 'C'], '']);
|
|
36
|
+
assert.deepStrictEqual(inspect(parser, input('bc', new Context())), [['B', 'C'], '']);
|
|
38
37
|
});
|
|
39
38
|
|
|
40
39
|
});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Parser, List,
|
|
1
|
+
import { Parser, List, Node, Context } from '../parser';
|
|
2
2
|
import { union } from './union';
|
|
3
3
|
import { inits } from './inits';
|
|
4
4
|
|
|
5
|
-
export function subsequence<P extends Parser>(parsers: SubParsers<P>, resume?: (nodes: List<
|
|
6
|
-
export function subsequence<N, D extends Parser<N>[]>(parsers: D, resume?: (nodes: List<
|
|
5
|
+
export function subsequence<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>>;
|
|
6
|
+
export function subsequence<N, D extends Parser<N>[]>(parsers: D, resume?: (nodes: List<Node<N>>) => boolean): Parser<N, Context, D> {
|
|
7
7
|
assert(parsers.every(f => f));
|
|
8
8
|
return union(
|
|
9
9
|
parsers.map((_, i) =>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Parser, List,
|
|
1
|
+
import { Parser, List, Node, Context } from '../parser';
|
|
2
2
|
import { union } from './union';
|
|
3
3
|
import { sequence } from './sequence';
|
|
4
4
|
|
|
5
|
-
export function tails<P extends Parser>(parsers: SubParsers<P>, resume?: (nodes: List<
|
|
6
|
-
export function tails<N, D extends Parser<N>[]>(parsers: D, resume?: (nodes: List<
|
|
5
|
+
export function tails<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>>;
|
|
6
|
+
export function tails<N, D extends Parser<N>[]>(parsers: D, resume?: (nodes: List<Node<N>>) => boolean): Parser<N, Context, D> {
|
|
7
7
|
return union(parsers.map((_, i) => sequence(parsers.slice(i), resume)) as D);
|
|
8
8
|
}
|
|
@@ -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 { inspect } from '../../../debug.test';
|
|
4
4
|
|
|
@@ -6,27 +6,26 @@ describe('Unit: combinator/data/parser/union', () => {
|
|
|
6
6
|
describe('union', () => {
|
|
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 = union<Parser<string,
|
|
18
|
-
const { context: ctx } = input('', {});
|
|
17
|
+
const ab = union<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())), [['A'], '']);
|
|
23
|
+
assert.deepStrictEqual(inspect(parser, input('b', new Context())), [['B'], '']);
|
|
24
|
+
assert.deepStrictEqual(inspect(parser, input('ab', new Context())), [['A'], 'b']);
|
|
25
|
+
assert.deepStrictEqual(inspect(parser, input('ba', new Context())), [['B'], 'a']);
|
|
26
|
+
assert.deepStrictEqual(inspect(parser, input('aab', new Context())), [['A'], 'ab']);
|
|
27
|
+
assert.deepStrictEqual(inspect(parser, input('abb', new Context())), [['A'], 'bb']);
|
|
28
|
+
assert.deepStrictEqual(inspect(parser, input('bba', new Context())), [['B'], 'ba']);
|
|
30
29
|
});
|
|
31
30
|
|
|
32
31
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Parser,
|
|
1
|
+
import { Parser, Context } from '../parser';
|
|
2
2
|
|
|
3
|
-
export function union<P extends Parser>(parsers: SubParsers<P>): SubNode<P> extends Node<P> ? P : Parser<SubNode<P>, Context<P>, SubParsers<P>>;
|
|
4
|
-
export function union<N, D extends Parser<N>[]>(parsers: D): Parser<N,
|
|
3
|
+
export function union<P extends Parser>(parsers: Parser.SubParsers<P>): Parser.SubNode<P> extends Parser.Node<P> ? P : Parser<Parser.SubNode<P>, Parser.Context<P>, Parser.SubParsers<P>>;
|
|
4
|
+
export function union<N, D extends Parser<N>[]>(parsers: D): Parser<N, Context, D> {
|
|
5
5
|
assert(parsers.every(f => f));
|
|
6
6
|
switch (parsers.length) {
|
|
7
7
|
case 0:
|