@futpib/parser 1.0.0 → 1.0.1
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/build/apk.d.ts +29 -3
- package/build/apkParser.d.ts +15 -2
- package/build/apkParser.js +70 -41
- package/build/apkParser.test.js +2 -2
- package/build/apkUnparser.d.ts +4 -0
- package/build/apkUnparser.js +90 -0
- package/build/apkUnparser.test.d.ts +1 -0
- package/build/apkUnparser.test.js +26 -0
- package/build/arbitraryFileSystemEntry.js +1 -1
- package/build/arbitraryZip.d.ts +1 -1
- package/build/arbitraryZip.js +13 -19
- package/build/arbitraryZipPermissions.d.ts +1 -8
- package/build/arbitraryZipPermissions.js +1 -16
- package/build/arbitraryZipStream.d.ts +1 -1
- package/build/arbitraryZipStream.js +3 -3
- package/build/arrayParser.d.ts +1 -1
- package/build/arrayParser.js +2 -2
- package/build/arrayParser.test.js +2 -2
- package/build/arrayUnparser.d.ts +2 -0
- package/build/arrayUnparser.js +8 -0
- package/build/bsonParser.test.js +2 -2
- package/build/customInvariant.d.ts +4 -0
- package/build/customInvariant.js +11 -0
- package/build/debugLogParser.d.ts +1 -1
- package/build/debugLogParser.js +1 -1
- package/build/elementParser.d.ts +2 -2
- package/build/elementParser.js +1 -1
- package/build/endOfInputParser.d.ts +2 -2
- package/build/exactElementParser.d.ts +1 -1
- package/build/exactSequenceParser.js +1 -1
- package/build/index.d.ts +5 -2
- package/build/index.js +3 -0
- package/build/inputReader.d.ts +3 -3
- package/build/inputReader.js +6 -6
- package/build/inputReader.test.js +7 -7
- package/build/javaKeyStore.d.ts +1 -0
- package/build/javaKeyStore.js +1 -0
- package/build/javaKeyStoreParser.d.ts +2 -0
- package/build/javaKeyStoreParser.js +67 -0
- package/build/javaKeyStoreParser.test.d.ts +1 -0
- package/build/javaKeyStoreParser.test.js +16 -0
- package/build/javaKeystoreParser.d.ts +2 -0
- package/build/javaKeystoreParser.js +7 -0
- package/build/jsonParser.js +3 -2
- package/build/jsonParser.test.js +2 -2
- package/build/listParser.d.ts +1 -1
- package/build/listParser.js +5 -5
- package/build/negativeLookahead.d.ts +1 -1
- package/build/negativeLookahead.js +16 -18
- package/build/negativeLookaheadParser.d.ts +2 -0
- package/build/negativeLookaheadParser.js +18 -0
- package/build/optionalParser.d.ts +1 -1
- package/build/optionalParser.js +2 -2
- package/build/parser.d.ts +3 -3
- package/build/parser.js +3 -3
- package/build/parser.test.js +16 -16
- package/build/parserAccessorParser.d.ts +1 -1
- package/build/parserConsumedSequenceParser.d.ts +2 -0
- package/build/parserConsumedSequenceParser.js +17 -0
- package/build/parserContext.d.ts +6 -6
- package/build/parserContext.js +15 -14
- package/build/parserContext.test.js +7 -7
- package/build/parserCreatorCompose.d.ts +3 -3
- package/build/parserCreatorCompose.js +2 -2
- package/build/parserImplementationInvariant.d.ts +1 -1
- package/build/parserImplementationInvariant.js +2 -2
- package/build/parserInputCompanion.d.ts +20 -0
- package/build/parserInputCompanion.js +30 -0
- package/build/parserInvariant.d.ts +1 -1
- package/build/parserInvariant.js +1 -1
- package/build/quantifierParser.d.ts +2 -0
- package/build/quantifierParser.js +17 -0
- package/build/sequenceBuffer.d.ts +3 -3
- package/build/sequenceBuffer.js +6 -6
- package/build/sequenceBuffer.test.js +2 -2
- package/build/sequenceUnparser.d.ts +2 -0
- package/build/sequenceUnparser.js +6 -0
- package/build/sliceBoundedParser.d.ts +1 -1
- package/build/sliceBoundedParser.js +1 -1
- package/build/sliceBoundedParser.test.js +2 -2
- package/build/terminatedArrayParser.d.ts +1 -1
- package/build/terminatedArrayParser.js +3 -3
- package/build/uint8Array.d.ts +1 -0
- package/build/uint8Array.js +7 -0
- package/build/unparser.d.ts +8 -0
- package/build/unparser.js +104 -0
- package/build/unparser.test.d.ts +1 -0
- package/build/unparser.test.js +150 -0
- package/build/unparserContext.d.ts +31 -0
- package/build/unparserContext.js +74 -0
- package/build/unparserError.d.ts +9 -0
- package/build/unparserError.js +9 -0
- package/build/unparserImplementationInvariant.d.ts +2 -0
- package/build/unparserImplementationInvariant.js +5 -0
- package/build/unparserInputCompanion.d.ts +15 -0
- package/build/unparserInputCompanion.js +13 -0
- package/build/unparserOutputCompanion.d.ts +15 -0
- package/build/unparserOutputCompanion.js +13 -0
- package/build/zip.d.ts +9 -17
- package/build/zipParser.d.ts +13 -10
- package/build/zipParser.js +48 -60
- package/build/zipParser.test.js +2 -7
- package/build/zipUnparser.d.ts +5 -0
- package/build/zipUnparser.js +171 -0
- package/build/zipUnparser.test.d.ts +1 -0
- package/build/zipUnparser.test.js +80 -0
- package/package.json +4 -2
- package/src/apk.ts +35 -3
- package/src/apkParser.test.ts +2 -2
- package/src/apkParser.test.ts.md +114 -111
- package/src/apkParser.test.ts.snap +0 -0
- package/src/apkParser.ts +150 -85
- package/src/apkUnparser.test.ts +37 -0
- package/src/apkUnparser.ts +120 -0
- package/src/arbitraryFileSystemEntry.ts +2 -4
- package/src/arbitraryZip.ts +20 -27
- package/src/arbitraryZipPermissions.ts +0 -25
- package/src/arbitraryZipStream.ts +4 -4
- package/src/arrayParser.test.ts +3 -3
- package/src/arrayParser.ts +3 -2
- package/src/arrayUnparser.ts +13 -0
- package/src/bsonParser.test.ts +2 -2
- package/src/bsonParser.ts +3 -3
- package/src/{parserInvariant.ts → customInvariant.ts} +1 -1
- package/src/debugLogParser.ts +1 -1
- package/src/elementParser.ts +3 -3
- package/src/endOfInputParser.ts +4 -4
- package/src/exactElementParser.ts +1 -1
- package/src/exactSequenceParser.ts +2 -2
- package/src/index.ts +15 -2
- package/src/inputReader.test.ts +7 -7
- package/src/inputReader.ts +5 -5
- package/src/javaKeyStore.ts +0 -0
- package/src/javaKeyStoreParser.test.ts +23 -0
- package/src/javaKeyStoreParser.test.ts.md +103 -0
- package/src/javaKeyStoreParser.test.ts.snap +0 -0
- package/src/javaKeyStoreParser.ts +136 -0
- package/src/jsonParser.test.ts +2 -2
- package/src/jsonParser.ts +13 -12
- package/src/listParser.ts +6 -6
- package/src/negativeLookaheadParser.ts +24 -0
- package/src/optionalParser.ts +3 -3
- package/src/parser.test.ts +19 -17
- package/src/parser.ts +7 -7
- package/src/parserAccessorParser.ts +1 -1
- package/src/parserConsumedSequenceParser.ts +20 -0
- package/src/parserContext.test.ts +7 -7
- package/src/parserContext.ts +18 -14
- package/src/parserCreatorCompose.ts +6 -6
- package/src/parserImplementationInvariant.ts +2 -2
- package/src/{inputCompanion.ts → parserInputCompanion.ts} +10 -6
- package/src/quantifierParser.ts +25 -0
- package/src/sequenceBuffer.test.ts +2 -2
- package/src/sequenceBuffer.ts +5 -5
- package/src/sequenceUnparser.ts +9 -0
- package/src/sliceBoundedParser.test.ts +2 -2
- package/src/sliceBoundedParser.ts +2 -2
- package/src/terminatedArrayParser.ts +3 -3
- package/src/uint8Array.ts +10 -0
- package/src/unparser.test.ts +221 -0
- package/src/unparser.ts +209 -0
- package/src/unparserContext.ts +127 -0
- package/src/unparserError.ts +12 -0
- package/src/unparserImplementationInvariant.ts +6 -0
- package/src/unparserOutputCompanion.ts +24 -0
- package/src/zip.ts +10 -22
- package/src/zipParser.test.ts +2 -8
- package/src/zipParser.ts +147 -129
- package/src/zipUnparser.test.ts +119 -0
- package/src/zipUnparser.ts +239 -0
- package/src/negativeLookahead.ts +0 -26
package/src/listParser.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { createNegativeLookaheadParser } from
|
|
2
|
-
import { Parser } from
|
|
3
|
-
import { createParserAccessorParser } from
|
|
4
|
-
import { promiseCompose } from
|
|
5
|
-
import { createTupleParser } from
|
|
6
|
-
import { createUnionParser } from
|
|
1
|
+
import { createNegativeLookaheadParser } from './negativeLookaheadParser.js';
|
|
2
|
+
import { type Parser } from './parser.js';
|
|
3
|
+
import { createParserAccessorParser } from './parserAccessorParser.js';
|
|
4
|
+
import { promiseCompose } from './promiseCompose.js';
|
|
5
|
+
import { createTupleParser } from './tupleParser.js';
|
|
6
|
+
import { createUnionParser } from './unionParser.js';
|
|
7
7
|
|
|
8
8
|
class Nil {}
|
|
9
9
|
class Cons<Head, Tail> {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { getParserName, type Parser } from './parser.js';
|
|
2
|
+
import { ParserParsingFailedError } from './parserError.js';
|
|
3
|
+
|
|
4
|
+
export const createNegativeLookaheadParser = <Sequence>(
|
|
5
|
+
childParser: Parser<unknown, Sequence>,
|
|
6
|
+
): Parser<void, Sequence> => async parserContext => {
|
|
7
|
+
const childParserContext = parserContext.lookahead();
|
|
8
|
+
try {
|
|
9
|
+
await childParser(childParserContext);
|
|
10
|
+
parserContext.invariant(
|
|
11
|
+
false,
|
|
12
|
+
'Negative lookahead assertion failed for child parser %s.',
|
|
13
|
+
getParserName(childParser),
|
|
14
|
+
);
|
|
15
|
+
} catch (error) {
|
|
16
|
+
if (error instanceof ParserParsingFailedError) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
throw error;
|
|
21
|
+
} finally {
|
|
22
|
+
childParserContext.dispose();
|
|
23
|
+
}
|
|
24
|
+
};
|
package/src/optionalParser.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { getParserName, Parser, setParserName } from
|
|
2
|
-
import { ParserParsingFailedError } from
|
|
1
|
+
import { getParserName, type Parser, setParserName } from './parser.js';
|
|
2
|
+
import { ParserParsingFailedError } from './parserError.js';
|
|
3
3
|
|
|
4
4
|
export const createOptionalParser = <Output, Sequence>(
|
|
5
5
|
childParser: Parser<Output, Sequence>,
|
|
@@ -24,4 +24,4 @@ export const createOptionalParser = <Output, Sequence>(
|
|
|
24
24
|
setParserName(optionalParser, getParserName(childParser, 'anonymousOptionalChild') + '?');
|
|
25
25
|
|
|
26
26
|
return optionalParser;
|
|
27
|
-
}
|
|
27
|
+
};
|
package/src/parser.test.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import test from 'ava';
|
|
2
|
+
import invariant from 'invariant';
|
|
2
3
|
import { createUnionParser } from './unionParser.js';
|
|
3
|
-
import { Parser, runParser } from './parser.js';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { type Parser, runParser } from './parser.js';
|
|
5
|
+
import { stringParserInputCompanion, uint8ArrayParserInputCompanion } from './parserInputCompanion.js';
|
|
6
|
+
import {
|
|
7
|
+
ParserParsingInvariantError, ParserParsingJoinAllError, ParserParsingJoinDeepestError, ParserParsingJoinError, ParserParsingJoinFurthestError, ParserParsingJoinNoneError,
|
|
8
|
+
} from './parserError.js';
|
|
6
9
|
import { createTupleParser } from './tupleParser.js';
|
|
7
10
|
import { promiseCompose } from './promiseCompose.js';
|
|
8
11
|
import { createDisjunctionParser } from './disjunctionParser.js';
|
|
9
|
-
import invariant from 'invariant';
|
|
10
12
|
import { createExactSequenceParser } from './exactSequenceParser.js';
|
|
11
13
|
import { createArrayParser } from './arrayParser.js';
|
|
12
14
|
import { createElementParser } from './elementParser.js';
|
|
@@ -55,14 +57,14 @@ function sortChildErrors(error: ParserParsingJoinNoneError) {
|
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
function removeStackLocations(errorStack: string) {
|
|
58
|
-
return errorStack.
|
|
60
|
+
return errorStack.replaceAll(/((at [^\n]+)[\s\n]+)+(at [^\n]+)/g, 'at [LOCATIONS]');
|
|
59
61
|
}
|
|
60
62
|
|
|
61
63
|
test('errorJoinMode: none', async t => {
|
|
62
|
-
const error = await t.throwsAsync(runParser(sampleParser, asyncIteratorFromString('1bbfinal_CC!'),
|
|
64
|
+
const error = await t.throwsAsync(runParser(sampleParser, asyncIteratorFromString('1bbfinal_CC!'), stringParserInputCompanion, {
|
|
63
65
|
errorJoinMode: 'none',
|
|
64
66
|
}), {
|
|
65
|
-
instanceOf: ParserParsingJoinNoneError
|
|
67
|
+
instanceOf: ParserParsingJoinNoneError,
|
|
66
68
|
});
|
|
67
69
|
|
|
68
70
|
t.is(error.position, 12);
|
|
@@ -72,10 +74,10 @@ test('errorJoinMode: none', async t => {
|
|
|
72
74
|
});
|
|
73
75
|
|
|
74
76
|
test('errorJoinMode: all', async t => {
|
|
75
|
-
const error = await t.throwsAsync(runParser(sampleParser, asyncIteratorFromString('1bbfinal_CC!'),
|
|
77
|
+
const error = await t.throwsAsync(runParser(sampleParser, asyncIteratorFromString('1bbfinal_CC!'), stringParserInputCompanion, {
|
|
76
78
|
errorJoinMode: 'all',
|
|
77
79
|
}), {
|
|
78
|
-
instanceOf: ParserParsingJoinAllError
|
|
80
|
+
instanceOf: ParserParsingJoinAllError,
|
|
79
81
|
});
|
|
80
82
|
|
|
81
83
|
sortChildErrors(error);
|
|
@@ -107,7 +109,7 @@ test('errorJoinMode: all', async t => {
|
|
|
107
109
|
});
|
|
108
110
|
|
|
109
111
|
test('errorJoinMode: deepest', async t => {
|
|
110
|
-
const error = await t.throwsAsync(runParser(sampleParser, asyncIteratorFromString('1bbfinal_CC!'),
|
|
112
|
+
const error = await t.throwsAsync(runParser(sampleParser, asyncIteratorFromString('1bbfinal_CC!'), stringParserInputCompanion, {
|
|
111
113
|
errorJoinMode: 'deepest',
|
|
112
114
|
}), {
|
|
113
115
|
instanceOf: ParserParsingJoinDeepestError,
|
|
@@ -142,7 +144,7 @@ test('errorJoinMode: deepest', async t => {
|
|
|
142
144
|
});
|
|
143
145
|
|
|
144
146
|
test('errorJoinMode: furthest', async t => {
|
|
145
|
-
const error = await t.throwsAsync(runParser(sampleParser, asyncIteratorFromString('1bbfinal_CC!'),
|
|
147
|
+
const error = await t.throwsAsync(runParser(sampleParser, asyncIteratorFromString('1bbfinal_CC!'), stringParserInputCompanion, {
|
|
146
148
|
errorJoinMode: 'furthest',
|
|
147
149
|
}), {
|
|
148
150
|
instanceOf: ParserParsingJoinFurthestError,
|
|
@@ -162,15 +164,15 @@ test('errorJoinMode: furthest', async t => {
|
|
|
162
164
|
t.is(error1.position, 12);
|
|
163
165
|
});
|
|
164
166
|
|
|
165
|
-
test('throws on
|
|
167
|
+
test('throws on parserInputCompanion type mismatch', async t => {
|
|
166
168
|
const anythingParser: Parser<any, any> = createArrayParser(createElementParser());
|
|
167
169
|
|
|
168
|
-
await runParser(anythingParser, asyncIteratorFromString('anything'),
|
|
169
|
-
await runParser(anythingParser, 'anything',
|
|
170
|
-
await runParser(anythingParser, Buffer.from('anything'),
|
|
171
|
-
await runParser(anythingParser, new Uint8Array([ 1, 2, 3 ]),
|
|
170
|
+
await runParser(anythingParser, asyncIteratorFromString('anything'), stringParserInputCompanion);
|
|
171
|
+
await runParser(anythingParser, 'anything', stringParserInputCompanion);
|
|
172
|
+
await runParser(anythingParser, Buffer.from('anything'), uint8ArrayParserInputCompanion);
|
|
173
|
+
await runParser(anythingParser, new Uint8Array([ 1, 2, 3 ]), uint8ArrayParserInputCompanion);
|
|
172
174
|
|
|
173
|
-
await t.throwsAsync(runParser(anythingParser, asyncIteratorFromString('anything'),
|
|
175
|
+
await t.throwsAsync(runParser(anythingParser, asyncIteratorFromString('anything'), uint8ArrayParserInputCompanion), {
|
|
174
176
|
message: /input companion/,
|
|
175
177
|
});
|
|
176
178
|
});
|
package/src/parser.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import invariant from 'invariant';
|
|
2
|
-
import { type
|
|
2
|
+
import { type ParserInputCompanion } from './parserInputCompanion.js';
|
|
3
3
|
import { InputReaderImplementation } from './inputReader.js';
|
|
4
4
|
import { type ParserContext, ParserContextImplementation } from './parserContext.js';
|
|
5
|
-
import { DeriveSequenceElement } from './sequence.js';
|
|
5
|
+
import { type DeriveSequenceElement } from './sequence.js';
|
|
6
6
|
|
|
7
7
|
export type Parser<
|
|
8
8
|
Output,
|
|
@@ -32,7 +32,7 @@ export type RunParserOptions<
|
|
|
32
32
|
Element = DeriveSequenceElement<Sequence>,
|
|
33
33
|
> = {
|
|
34
34
|
errorJoinMode?: 'none' | 'deepest' | 'furthest' | 'all';
|
|
35
|
-
}
|
|
35
|
+
};
|
|
36
36
|
|
|
37
37
|
function isAsyncIterable<T>(value: any): value is AsyncIterable<T> {
|
|
38
38
|
return value && typeof value[Symbol.asyncIterator] === 'function';
|
|
@@ -57,7 +57,7 @@ function toAsyncIterator<T>(value: AsyncIterator<T> | AsyncIterable<T> | Iterabl
|
|
|
57
57
|
typeof value === 'string'
|
|
58
58
|
|| value instanceof Uint8Array
|
|
59
59
|
) {
|
|
60
|
-
return (async function*() {
|
|
60
|
+
return (async function * () {
|
|
61
61
|
yield value as any;
|
|
62
62
|
})();
|
|
63
63
|
}
|
|
@@ -88,13 +88,13 @@ export async function runParser<
|
|
|
88
88
|
>(
|
|
89
89
|
parser: Parser<Output, Sequence, Element>,
|
|
90
90
|
input: AsyncIterator<Sequence> | AsyncIterable<Sequence> | Iterable<Sequence> | Sequence,
|
|
91
|
-
|
|
91
|
+
parserInputCompanion: ParserInputCompanion<Sequence, Element>,
|
|
92
92
|
options: RunParserOptions<Output, Sequence, Element> = {},
|
|
93
93
|
): Promise<Output> {
|
|
94
94
|
const inputAsyncIterator = toAsyncIterator(input);
|
|
95
95
|
|
|
96
|
-
const inputReader = new InputReaderImplementation<Sequence, Element>(
|
|
97
|
-
const parserContext = new ParserContextImplementation<Sequence, Element>(
|
|
96
|
+
const inputReader = new InputReaderImplementation<Sequence, Element>(parserInputCompanion, inputAsyncIterator);
|
|
97
|
+
const parserContext = new ParserContextImplementation<Sequence, Element>(parserInputCompanion, inputReader, undefined, {
|
|
98
98
|
...options,
|
|
99
99
|
debugName: 'root',
|
|
100
100
|
});
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { Parser } from
|
|
1
|
+
import { type Parser } from './parser.js';
|
|
2
2
|
|
|
3
3
|
export const createParserAccessorParser = <Output, Sequence>(parserAccessor: () => Parser<Output, Sequence>): Parser<Output, Sequence> => async parserContext => parserAccessor()(parserContext);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createFixedLengthSequenceParser } from "./fixedLengthSequenceParser.js";
|
|
2
|
+
import { Parser } from "./parser.js";
|
|
3
|
+
|
|
4
|
+
export const createParserConsumedSequenceParser = <Output, Sequence>(
|
|
5
|
+
childParser: Parser<Output, Sequence>,
|
|
6
|
+
): Parser<[Output, Sequence], Sequence> => async parserContext => {
|
|
7
|
+
const initialPosition = parserContext.position;
|
|
8
|
+
const childParserContext = parserContext.lookahead();
|
|
9
|
+
let value: Output;
|
|
10
|
+
let consumedLength: number;
|
|
11
|
+
try {
|
|
12
|
+
value = await childParser(childParserContext);
|
|
13
|
+
consumedLength = childParserContext.position - initialPosition;
|
|
14
|
+
} finally {
|
|
15
|
+
childParserContext.dispose();
|
|
16
|
+
}
|
|
17
|
+
const consumedSequenceParser = createFixedLengthSequenceParser<Sequence>(consumedLength);
|
|
18
|
+
const consumedSequence = await consumedSequenceParser(parserContext);
|
|
19
|
+
return [value, consumedSequence];
|
|
20
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import test from 'ava';
|
|
2
2
|
import { ParserContextImplementation } from './parserContext.js';
|
|
3
|
-
import {
|
|
3
|
+
import { stringParserInputCompanion } from './parserInputCompanion.js';
|
|
4
4
|
import { InputReaderImplementation } from './inputReader.js';
|
|
5
5
|
import { ParserUnexpectedEndOfInputError } from './parserError.js';
|
|
6
6
|
|
|
@@ -13,7 +13,7 @@ const commonParserContextArguments = [
|
|
|
13
13
|
] as const;
|
|
14
14
|
|
|
15
15
|
test('parserContext.read', async t => {
|
|
16
|
-
const parserContext = new ParserContextImplementation(
|
|
16
|
+
const parserContext = new ParserContextImplementation(stringParserInputCompanion, new InputReaderImplementation(stringParserInputCompanion, (async function * () {
|
|
17
17
|
yield '';
|
|
18
18
|
yield 'abc';
|
|
19
19
|
yield 'def';
|
|
@@ -31,7 +31,7 @@ test('parserContext.read', async t => {
|
|
|
31
31
|
});
|
|
32
32
|
|
|
33
33
|
test('parserContext.lookahead', async t => {
|
|
34
|
-
const parserContext = new ParserContextImplementation(
|
|
34
|
+
const parserContext = new ParserContextImplementation(stringParserInputCompanion, new InputReaderImplementation(stringParserInputCompanion, (async function * () {
|
|
35
35
|
yield * 'abcdefgh';
|
|
36
36
|
})()), ...commonParserContextArguments);
|
|
37
37
|
|
|
@@ -66,7 +66,7 @@ test('parserContext.lookahead', async t => {
|
|
|
66
66
|
});
|
|
67
67
|
|
|
68
68
|
test('parserContext.unlookahead', async t => {
|
|
69
|
-
const parserContext = new ParserContextImplementation(
|
|
69
|
+
const parserContext = new ParserContextImplementation(stringParserInputCompanion, new InputReaderImplementation(stringParserInputCompanion, (async function * () {
|
|
70
70
|
yield * 'abcdefgh';
|
|
71
71
|
})()), ...commonParserContextArguments);
|
|
72
72
|
|
|
@@ -86,7 +86,7 @@ test('parserContext.unlookahead', async t => {
|
|
|
86
86
|
});
|
|
87
87
|
|
|
88
88
|
test('parserContext.unlookahead while peeking', async t => {
|
|
89
|
-
const parserContext = new ParserContextImplementation(
|
|
89
|
+
const parserContext = new ParserContextImplementation(stringParserInputCompanion, new InputReaderImplementation(stringParserInputCompanion, (async function * () {
|
|
90
90
|
yield * 'abcdefgh';
|
|
91
91
|
})()), ...commonParserContextArguments);
|
|
92
92
|
|
|
@@ -103,7 +103,7 @@ test('parserContext.unlookahead while peeking', async t => {
|
|
|
103
103
|
});
|
|
104
104
|
|
|
105
105
|
test('parserContext deep unlookahead normal order', async t => {
|
|
106
|
-
const parserContext = new ParserContextImplementation(
|
|
106
|
+
const parserContext = new ParserContextImplementation(stringParserInputCompanion, new InputReaderImplementation(stringParserInputCompanion, (async function * () {
|
|
107
107
|
yield * 'abcdefgh';
|
|
108
108
|
})()), ...commonParserContextArguments);
|
|
109
109
|
|
|
@@ -125,7 +125,7 @@ test('parserContext deep unlookahead normal order', async t => {
|
|
|
125
125
|
});
|
|
126
126
|
|
|
127
127
|
test('parserContext deep unlookahead weird order', async t => {
|
|
128
|
-
const parserContext = new ParserContextImplementation(
|
|
128
|
+
const parserContext = new ParserContextImplementation(stringParserInputCompanion, new InputReaderImplementation(stringParserInputCompanion, (async function * () {
|
|
129
129
|
yield * 'abcdefgh';
|
|
130
130
|
})()), ...commonParserContextArguments);
|
|
131
131
|
|
package/src/parserContext.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
/* eslint-disable prefer-arrow-callback */
|
|
2
|
+
|
|
1
3
|
import invariant from 'invariant';
|
|
2
|
-
import { type
|
|
4
|
+
import { type ParserInputCompanion } from './parserInputCompanion.js';
|
|
3
5
|
import { type InputReader } from './inputReader.js';
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
import {
|
|
7
|
+
type ParserParsingFailedError, ParserUnexpectedEndOfInputError, ParserParsingInvariantError, ParserParsingJoinNoneError, ParserParsingJoinAllError, ParserParsingJoinDeepestError, ParserParsingJoinFurthestError,
|
|
8
|
+
} from './parserError.js';
|
|
9
|
+
import { type RunParserOptions } from './parser.js';
|
|
10
|
+
import { type Falsy, customInvariant, type ValueOrAccessor } from './customInvariant.js';
|
|
7
11
|
|
|
8
12
|
type LookaheadOptions = {
|
|
9
13
|
debugName?: string;
|
|
@@ -43,7 +47,7 @@ export class ParserContextImplementation<Sequence, Element> implements ParserCon
|
|
|
43
47
|
private _exclusiveChildParserContext: ParserContext<Sequence, Element> | undefined = undefined;
|
|
44
48
|
|
|
45
49
|
constructor(
|
|
46
|
-
private readonly
|
|
50
|
+
private readonly _parserInputCompanion: ParserInputCompanion<Sequence, Element>,
|
|
47
51
|
private _inputReader: InputReader<Sequence, Element>,
|
|
48
52
|
private _parentParserContext: ParserContextImplementation<Sequence, Element> | undefined = undefined,
|
|
49
53
|
private readonly _options: ParserContextOptions<Sequence, Element>,
|
|
@@ -65,15 +69,15 @@ export class ParserContextImplementation<Sequence, Element> implements ParserCon
|
|
|
65
69
|
}
|
|
66
70
|
|
|
67
71
|
from(elements: Element[]): Sequence {
|
|
68
|
-
return this.
|
|
72
|
+
return this._parserInputCompanion.from(elements);
|
|
69
73
|
}
|
|
70
74
|
|
|
71
75
|
length(sequence: Sequence): number {
|
|
72
|
-
return this.
|
|
76
|
+
return this._parserInputCompanion.length(sequence);
|
|
73
77
|
}
|
|
74
78
|
|
|
75
79
|
at(sequence: Sequence, index: number): Element | undefined {
|
|
76
|
-
return this.
|
|
80
|
+
return this._parserInputCompanion.at(sequence, index);
|
|
77
81
|
}
|
|
78
82
|
|
|
79
83
|
get position() {
|
|
@@ -122,7 +126,7 @@ export class ParserContextImplementation<Sequence, Element> implements ParserCon
|
|
|
122
126
|
);
|
|
123
127
|
|
|
124
128
|
const lookaheadParserContext = new ParserContextImplementation(
|
|
125
|
-
this.
|
|
129
|
+
this._parserInputCompanion,
|
|
126
130
|
lookaheadInputReader,
|
|
127
131
|
this,
|
|
128
132
|
{
|
|
@@ -221,7 +225,7 @@ export class ParserContextImplementation<Sequence, Element> implements ParserCon
|
|
|
221
225
|
invariant<T>(value: T, format: ValueOrAccessor<string | string[]>, ...formatArguments: any[]): Exclude<T, Falsy> {
|
|
222
226
|
const parserContext = this;
|
|
223
227
|
|
|
224
|
-
return
|
|
228
|
+
return customInvariant(function (message: string) {
|
|
225
229
|
return new ParserParsingInvariantError(message, parserContext._depth, parserContext.position);
|
|
226
230
|
}, value, format, ...formatArguments);
|
|
227
231
|
}
|
|
@@ -233,13 +237,13 @@ export class ParserContextImplementation<Sequence, Element> implements ParserCon
|
|
|
233
237
|
const parserContext = this;
|
|
234
238
|
|
|
235
239
|
if (errorJoinMode === 'none') {
|
|
236
|
-
return
|
|
240
|
+
return customInvariant(function (message: string) {
|
|
237
241
|
return new ParserParsingJoinNoneError(message, parserContext._depth, parserContext.position);
|
|
238
242
|
}, value, format, ...formatArguments);
|
|
239
243
|
}
|
|
240
244
|
|
|
241
245
|
if (errorJoinMode === 'furthest') {
|
|
242
|
-
return
|
|
246
|
+
return customInvariant(function (message: string) {
|
|
243
247
|
let furthestPosition = 0;
|
|
244
248
|
let furthestChildErrors: ParserParsingFailedError[] = [];
|
|
245
249
|
|
|
@@ -269,7 +273,7 @@ export class ParserContextImplementation<Sequence, Element> implements ParserCon
|
|
|
269
273
|
}
|
|
270
274
|
|
|
271
275
|
if (errorJoinMode === 'deepest') {
|
|
272
|
-
return
|
|
276
|
+
return customInvariant(function (message: string) {
|
|
273
277
|
let deepestDepth = 0;
|
|
274
278
|
let deepestChildErrors: ParserParsingFailedError[] = [];
|
|
275
279
|
|
|
@@ -299,7 +303,7 @@ export class ParserContextImplementation<Sequence, Element> implements ParserCon
|
|
|
299
303
|
}
|
|
300
304
|
|
|
301
305
|
if (errorJoinMode === 'all') {
|
|
302
|
-
return
|
|
306
|
+
return customInvariant(function (message: string) {
|
|
303
307
|
message += [
|
|
304
308
|
'',
|
|
305
309
|
'Child error stacks, indented:',
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Parser } from
|
|
2
|
-
import { DeriveSequenceElement } from
|
|
1
|
+
import { type Parser } from './parser.js';
|
|
2
|
+
import { type DeriveSequenceElement } from './sequence.js';
|
|
3
3
|
|
|
4
4
|
export function parserCreatorCompose<
|
|
5
5
|
Arguments extends unknown[],
|
|
@@ -8,11 +8,11 @@ export function parserCreatorCompose<
|
|
|
8
8
|
Sequence,
|
|
9
9
|
Element = DeriveSequenceElement<Sequence>,
|
|
10
10
|
>(
|
|
11
|
-
f1: (...
|
|
11
|
+
f1: (...arguments_: Arguments) => Parser<OutputA, Sequence, Element>,
|
|
12
12
|
f2: (outputA: OutputA) => Parser<OutputB, Sequence, Element>,
|
|
13
|
-
): (...
|
|
14
|
-
return (...
|
|
15
|
-
const parserA = f1(...
|
|
13
|
+
): (...arguments_: Arguments) => Parser<OutputB, Sequence, Element> {
|
|
14
|
+
return (...arguments_) => {
|
|
15
|
+
const parserA = f1(...arguments_);
|
|
16
16
|
|
|
17
17
|
return async parserContext => {
|
|
18
18
|
const outputA = await parserA(parserContext);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ParserImplementationInvariantError } from './parserError.js';
|
|
2
|
-
import { type Falsy,
|
|
2
|
+
import { type Falsy, customInvariant, type ValueOrAccessor } from './customInvariant.js';
|
|
3
3
|
|
|
4
4
|
export function parserImplementationInvariant<T>(value: T, format: ValueOrAccessor<string | string[]>, ...formatArguments: any[]): Exclude<T, Falsy> {
|
|
5
|
-
return
|
|
5
|
+
return customInvariant(ParserImplementationInvariantError, value, format, ...formatArguments);
|
|
6
6
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
|
|
2
|
-
export type
|
|
2
|
+
export type ParserInputCompanion<Sequence, Element> = {
|
|
3
3
|
is(value: unknown): value is Sequence;
|
|
4
4
|
from(elements: Element[]): Sequence;
|
|
5
5
|
length(sequence: Sequence): number;
|
|
6
6
|
at(sequence: Sequence, index: number): Element | undefined;
|
|
7
7
|
};
|
|
8
8
|
|
|
9
|
-
export
|
|
9
|
+
export class StringParserInputCompanion implements ParserInputCompanion<string, string> {
|
|
10
10
|
is(value: unknown): value is string {
|
|
11
11
|
return typeof value === 'string';
|
|
12
12
|
}
|
|
@@ -22,11 +22,13 @@ export const stringInputCompanion = new class StringInputCompanion implements In
|
|
|
22
22
|
at(sequence: string, index: number): string | undefined {
|
|
23
23
|
return sequence.at(index);
|
|
24
24
|
}
|
|
25
|
-
}
|
|
25
|
+
}
|
|
26
26
|
|
|
27
|
-
export const
|
|
27
|
+
export const stringParserInputCompanion = new StringParserInputCompanion();
|
|
28
|
+
|
|
29
|
+
export class Uint8ArrayParserInputCompanion implements ParserInputCompanion<Uint8Array, number> {
|
|
28
30
|
is(value: unknown): value is Uint8Array {
|
|
29
|
-
return value instanceof Uint8Array
|
|
31
|
+
return value instanceof Uint8Array;
|
|
30
32
|
}
|
|
31
33
|
|
|
32
34
|
from(elements: number[]): Uint8Array {
|
|
@@ -40,4 +42,6 @@ export const uint8ArrayInputCompanion = new class Uint8ArrayInputCompanion imple
|
|
|
40
42
|
at(sequence: Uint8Array, index: number): number | undefined {
|
|
41
43
|
return sequence.at(index);
|
|
42
44
|
}
|
|
43
|
-
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export const uint8ArrayParserInputCompanion = new Uint8ArrayParserInputCompanion();
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { getParserName, type Parser, setParserName } from './parser.js';
|
|
2
|
+
|
|
3
|
+
export const createQuantifierParser = <Output, Sequence>(
|
|
4
|
+
childParser: Parser<Output, Sequence>,
|
|
5
|
+
count: number,
|
|
6
|
+
): Parser<Output[], Sequence> => {
|
|
7
|
+
const quantifierParser: Parser<Output[], Sequence> = async parserContext => {
|
|
8
|
+
const elements: Output[] = [];
|
|
9
|
+
|
|
10
|
+
for (let index = 0; index < count; index++) {
|
|
11
|
+
elements.push(await childParser(parserContext));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return elements;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
setParserName(quantifierParser, [
|
|
18
|
+
getParserName(childParser, 'anonymousQuantifierChild'),
|
|
19
|
+
'{',
|
|
20
|
+
count,
|
|
21
|
+
'}',
|
|
22
|
+
].join(''));
|
|
23
|
+
|
|
24
|
+
return quantifierParser;
|
|
25
|
+
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import test from 'ava';
|
|
2
2
|
import { SequenceBufferImplementation } from './sequenceBuffer.js';
|
|
3
|
-
import {
|
|
3
|
+
import { stringParserInputCompanion } from './parserInputCompanion.js';
|
|
4
4
|
|
|
5
5
|
test('sequenceBuffer', t => {
|
|
6
|
-
const sequenceBuffer = new SequenceBufferImplementation(
|
|
6
|
+
const sequenceBuffer = new SequenceBufferImplementation(stringParserInputCompanion);
|
|
7
7
|
|
|
8
8
|
t.is(sequenceBuffer.peek(0), undefined);
|
|
9
9
|
|
package/src/sequenceBuffer.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import invariant from 'invariant';
|
|
2
|
-
import { type
|
|
2
|
+
import { type ParserInputCompanion } from './parserInputCompanion.js';
|
|
3
3
|
|
|
4
4
|
export type SequenceBuffer<Sequence, Element> = {
|
|
5
5
|
push(sequence: Sequence): void;
|
|
@@ -11,14 +11,14 @@ export class SequenceBufferImplementation<Sequence, Element> implements Sequence
|
|
|
11
11
|
private readonly _sequences: Sequence[] = [];
|
|
12
12
|
private _indexInFirstSequence = 0;
|
|
13
13
|
|
|
14
|
-
constructor(private readonly
|
|
14
|
+
constructor(private readonly _parserInputCompanion: ParserInputCompanion<Sequence, Element>) {}
|
|
15
15
|
|
|
16
16
|
push(sequence: Sequence) {
|
|
17
17
|
this._sequences.push(sequence);
|
|
18
18
|
|
|
19
19
|
while (this._sequences.length > 0) {
|
|
20
20
|
const firstSequence = this._sequences[0];
|
|
21
|
-
const firstSequenceLength = this.
|
|
21
|
+
const firstSequenceLength = this._parserInputCompanion.length(firstSequence);
|
|
22
22
|
|
|
23
23
|
if (firstSequenceLength === 0) {
|
|
24
24
|
this._sequences.shift();
|
|
@@ -40,10 +40,10 @@ export class SequenceBufferImplementation<Sequence, Element> implements Sequence
|
|
|
40
40
|
let index = this._indexInFirstSequence + offset;
|
|
41
41
|
|
|
42
42
|
for (const sequence of this._sequences) {
|
|
43
|
-
const sequenceLength = this.
|
|
43
|
+
const sequenceLength = this._parserInputCompanion.length(sequence);
|
|
44
44
|
|
|
45
45
|
if (index < sequenceLength) {
|
|
46
|
-
return this.
|
|
46
|
+
return this._parserInputCompanion.at(sequence, index);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
index -= sequenceLength;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Unparser } from "./unparser.js";
|
|
2
|
+
|
|
3
|
+
export const createSequenceUnparser = <Sequence>(): Unparser<Sequence, Sequence> => {
|
|
4
|
+
const sequenceUnparser: Unparser<Sequence, Sequence> = async function * (input) {
|
|
5
|
+
yield input;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
return sequenceUnparser;
|
|
9
|
+
}
|
|
@@ -4,7 +4,7 @@ import { createElementParser } from './elementParser.js';
|
|
|
4
4
|
import { createTupleParser } from './tupleParser.js';
|
|
5
5
|
import { createSliceBoundedParser } from './sliceBoundedParser.js';
|
|
6
6
|
import { runParser } from './parser.js';
|
|
7
|
-
import {
|
|
7
|
+
import { stringParserInputCompanion } from './parserInputCompanion.js';
|
|
8
8
|
|
|
9
9
|
const anythingParser = createArrayParser(createElementParser<string>());
|
|
10
10
|
|
|
@@ -15,7 +15,7 @@ test('sliceBoundedParser', async t => {
|
|
|
15
15
|
createElementParser(),
|
|
16
16
|
]);
|
|
17
17
|
|
|
18
|
-
const result = await runParser(parser, 'abba',
|
|
18
|
+
const result = await runParser(parser, 'abba', stringParserInputCompanion);
|
|
19
19
|
|
|
20
20
|
t.deepEqual(result, [
|
|
21
21
|
'a',
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getParserName, Parser, setParserName } from
|
|
1
|
+
import { getParserName, type Parser, setParserName } from './parser.js';
|
|
2
2
|
|
|
3
3
|
export const createSliceBoundedParser = <Output, Sequence>(
|
|
4
4
|
childParser: Parser<Output, Sequence>,
|
|
@@ -27,4 +27,4 @@ export const createSliceBoundedParser = <Output, Sequence>(
|
|
|
27
27
|
].join(''));
|
|
28
28
|
|
|
29
29
|
return sliceBoundedParser;
|
|
30
|
-
}
|
|
30
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { getParserName, Parser, setParserName } from
|
|
2
|
-
import { promiseCompose } from
|
|
3
|
-
import { createUnionParser } from
|
|
1
|
+
import { getParserName, type Parser, setParserName } from './parser.js';
|
|
2
|
+
import { promiseCompose } from './promiseCompose.js';
|
|
3
|
+
import { createUnionParser } from './unionParser.js';
|
|
4
4
|
|
|
5
5
|
class Terminated<T> {
|
|
6
6
|
constructor(
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
|
|
2
|
+
export async function uint8ArrayAsyncIterableToUint8Array(
|
|
3
|
+
uint8ArrayAsyncIterable: AsyncIterable<Uint8Array> | Iterable<Uint8Array>,
|
|
4
|
+
): Promise<Uint8Array> {
|
|
5
|
+
const chunks: Uint8Array[] = [];
|
|
6
|
+
for await (const chunk of uint8ArrayAsyncIterable) {
|
|
7
|
+
chunks.push(chunk);
|
|
8
|
+
}
|
|
9
|
+
return Buffer.concat(chunks);
|
|
10
|
+
}
|