@futpib/parser 1.0.0 → 1.0.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/build/allSettledStream.js +32 -14
- package/build/allSettledStream.test.js +32 -0
- package/build/androidPackage.d.ts +39 -0
- package/build/androidPackageParser.d.ts +17 -0
- package/build/androidPackageParser.js +183 -0
- package/build/{apkParser.test.js → androidPackageParser.test.js} +7 -7
- package/build/androidPackageUnparser.d.ts +4 -0
- package/build/androidPackageUnparser.js +90 -0
- package/build/androidPackageUnparser.test.js +26 -0
- package/build/arbitrarilySlicedAsyncInterable.d.ts +3 -1
- package/build/arbitrarilySlicedAsyncInterable.js +3 -3
- 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 +4 -4
- package/build/arrayUnparser.d.ts +2 -0
- package/build/arrayUnparser.js +8 -0
- package/build/backsmali.d.ts +1 -0
- package/build/backsmali.js +22 -0
- package/build/bsonParser.js +6 -2
- package/build/bsonParser.test.js +2 -2
- package/build/{parserInvariant.d.ts → customInvariant.d.ts} +1 -1
- package/build/{parserInvariant.js → customInvariant.js} +1 -1
- package/build/dalvikBytecodeParser/formatParsers.d.ts +97 -0
- package/build/dalvikBytecodeParser/formatParsers.js +169 -0
- package/build/dalvikBytecodeParser.d.ts +107 -0
- package/build/dalvikBytecodeParser.js +836 -0
- package/build/dalvikExecutable.d.ts +158 -0
- package/build/dalvikExecutable.js +20 -0
- package/build/dalvikExecutableParser/stringSyntaxParser.d.ts +4 -0
- package/build/dalvikExecutableParser/stringSyntaxParser.js +76 -0
- package/build/dalvikExecutableParser/typeParsers.d.ts +10 -0
- package/build/dalvikExecutableParser/typeParsers.js +34 -0
- package/build/dalvikExecutableParser/typedNumbers.d.ts +90 -0
- package/build/dalvikExecutableParser/typedNumbers.js +19 -0
- package/build/dalvikExecutableParser.d.ts +5 -0
- package/build/dalvikExecutableParser.js +1439 -0
- package/build/dalvikExecutableParser.test.js +70 -0
- package/build/dalvikExecutableParserAgainstSmaliParser.test.js +298 -0
- package/build/debugLogInputParser.d.ts +4 -0
- package/build/debugLogInputParser.js +16 -0
- package/build/debugLogParser.d.ts +1 -1
- package/build/debugLogParser.js +15 -4
- package/build/disjunctionParser.d.ts +2 -1
- package/build/disjunctionParser.js +4 -2
- package/build/elementParser.d.ts +2 -2
- package/build/elementParser.js +1 -1
- package/build/elementTerminatedArrayParser.d.ts +3 -0
- package/build/elementTerminatedArrayParser.js +18 -0
- package/build/elementTerminatedArrayParser.test.js +52 -0
- package/build/elementTerminatedSequenceArrayParser.d.ts +3 -0
- package/build/elementTerminatedSequenceArrayParser.js +32 -0
- package/build/elementTerminatedSequenceArrayParser.test.js +34 -0
- package/build/elementTerminatedSequenceParser.d.ts +3 -0
- package/build/elementTerminatedSequenceParser.js +27 -0
- package/build/elementTerminatedSequenceParser.test.js +34 -0
- package/build/endOfInputParser.d.ts +2 -2
- package/build/exactElementParser.d.ts +1 -1
- package/build/exactElementParser.js +10 -5
- package/build/exactSequenceParser.d.ts +2 -1
- package/build/exactSequenceParser.js +12 -2
- package/build/fetchCid.d.ts +1 -0
- package/build/fetchCid.js +107 -0
- package/build/fixedLengthSequenceParser.d.ts +1 -0
- package/build/fixedLengthSequenceParser.js +18 -1
- package/build/fixedLengthSequenceParser.test.js +41 -0
- package/build/hasExecutable.d.ts +1 -0
- package/build/hasExecutable.js +8 -0
- package/build/highResolutionTimer.d.ts +16 -0
- package/build/highResolutionTimer.js +42 -0
- package/build/index.d.ts +5 -2
- package/build/index.js +3 -0
- package/build/inputReader.d.ts +14 -3
- package/build/inputReader.js +43 -6
- package/build/inputReader.test.js +172 -7
- package/build/inputReaderState.d.ts +10 -0
- package/build/inputReaderState.js +16 -0
- package/build/inspect.d.ts +1 -0
- package/build/inspect.js +7 -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/jsonParser.d.ts +2 -0
- package/build/jsonParser.js +13 -15
- package/build/jsonParser.test.js +2 -2
- package/build/leb128Parser.d.ts +7 -0
- package/build/leb128Parser.js +82 -0
- package/build/leb128Parser.test.d.ts +1 -0
- package/build/leb128Parser.test.js +107 -0
- package/build/listParser.d.ts +1 -1
- package/build/listParser.js +5 -5
- package/build/lookaheadParser.d.ts +2 -0
- package/build/lookaheadParser.js +14 -0
- package/build/{negativeLookahead.d.ts → negativeLookaheadParser.d.ts} +1 -1
- package/build/negativeLookaheadParser.js +24 -0
- package/build/negativeLookaheadParser.test.d.ts +1 -0
- package/build/negativeLookaheadParser.test.js +30 -0
- package/build/nonEmptyArrayParser.d.ts +2 -0
- package/build/nonEmptyArrayParser.js +32 -0
- package/build/nonEmptyArrayParser.test.d.ts +1 -0
- package/build/nonEmptyArrayParser.test.js +16 -0
- package/build/optionalParser.d.ts +1 -1
- package/build/optionalParser.js +2 -2
- package/build/parser.d.ts +13 -4
- package/build/parser.js +67 -32
- package/build/parser.test.js +94 -27
- package/build/parserAccessorParser.d.ts +1 -1
- package/build/parserAccessorParser.js +9 -1
- package/build/parserConsumedSequenceParser.d.ts +2 -0
- package/build/parserConsumedSequenceParser.js +22 -0
- package/build/parserContext.d.ts +20 -6
- package/build/parserContext.js +70 -40
- package/build/parserContext.test.js +34 -7
- package/build/parserCreatorCompose.d.ts +4 -3
- package/build/parserCreatorCompose.js +9 -3
- package/build/parserError.d.ts +6 -0
- package/build/parserError.js +6 -6
- package/build/parserImplementationInvariant.d.ts +1 -1
- package/build/parserImplementationInvariant.js +2 -2
- package/build/parserInputCompanion.d.ts +35 -0
- package/build/parserInputCompanion.js +68 -0
- package/build/promiseCompose.d.ts +1 -1
- package/build/promiseCompose.js +12 -1
- package/build/promiseSettled.d.ts +1 -0
- package/build/promiseSettled.js +4 -0
- package/build/quantifierParser.d.ts +2 -0
- package/build/quantifierParser.js +17 -0
- package/build/separatedArrayParser.d.ts +2 -0
- package/build/separatedArrayParser.js +39 -0
- package/build/separatedArrayParser.test.d.ts +1 -0
- package/build/separatedArrayParser.test.js +21 -0
- package/build/sequenceBuffer.d.ts +13 -3
- package/build/sequenceBuffer.js +60 -8
- package/build/sequenceBuffer.test.js +59 -2
- package/build/sequenceTerminatedSequenceParser.d.ts +5 -0
- package/build/sequenceTerminatedSequenceParser.js +32 -0
- package/build/sequenceTerminatedSequenceParser.test.d.ts +1 -0
- package/build/sequenceTerminatedSequenceParser.test.js +37 -0
- package/build/sequenceUnparser.d.ts +2 -0
- package/build/sequenceUnparser.js +6 -0
- package/build/skipParser.d.ts +1 -1
- package/build/skipParser.js +4 -2
- package/build/skipToParser.d.ts +2 -0
- package/build/skipToParser.js +11 -0
- package/build/sliceBoundedParser.d.ts +2 -2
- package/build/sliceBoundedParser.js +8 -3
- package/build/sliceBoundedParser.test.js +37 -3
- package/build/smali.d.ts +1 -0
- package/build/smali.js +17 -0
- package/build/smaliParser.d.ts +12 -0
- package/build/smaliParser.js +656 -0
- package/build/smaliParser.test.d.ts +1 -0
- package/build/smaliParser.test.js +115 -0
- package/build/terminatedArrayParser.d.ts +4 -2
- package/build/terminatedArrayParser.js +82 -5
- package/build/terminatedArrayParser.test.d.ts +1 -0
- package/build/terminatedArrayParser.test.js +131 -0
- package/build/toAsyncIterable.d.ts +1 -0
- package/build/toAsyncIterable.js +7 -0
- package/build/toAsyncIterator.d.ts +1 -0
- package/build/toAsyncIterator.js +33 -0
- package/build/tupleParser.d.ts +4 -0
- package/build/tupleParser.js +1 -5
- package/build/uint8Array.d.ts +1 -0
- package/build/uint8Array.js +7 -0
- package/build/unionParser.d.ts +2 -1
- package/build/unionParser.js +27 -12
- package/build/unionParser.test.d.ts +1 -0
- package/build/unionParser.test.js +60 -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/unparserOutputCompanion.d.ts +15 -0
- package/build/unparserOutputCompanion.js +13 -0
- package/build/zip.d.ts +9 -17
- package/build/zipParser.d.ts +20 -12
- package/build/zipParser.js +83 -71
- package/build/zipParser.test.js +2 -7
- package/build/zipUnparser.d.ts +8 -0
- package/build/zipUnparser.js +200 -0
- package/build/zipUnparser.test.d.ts +1 -0
- package/build/zipUnparser.test.js +80 -0
- package/package.json +26 -8
- package/src/allSettledStream.test.ts +40 -0
- package/src/allSettledStream.ts +47 -15
- package/src/androidPackage.ts +48 -0
- package/src/{apkParser.test.ts → androidPackageParser.test.ts} +7 -8
- package/src/androidPackageParser.test.ts.md +271 -0
- package/src/androidPackageParser.test.ts.snap +0 -0
- package/src/androidPackageParser.ts +440 -0
- package/src/androidPackageUnparser.test.ts +36 -0
- package/src/androidPackageUnparser.ts +120 -0
- package/src/arbitrarilySlicedAsyncInterable.ts +7 -2
- 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 +4 -4
- package/src/arrayParser.ts +3 -2
- package/src/arrayUnparser.ts +13 -0
- package/src/backsmali.ts +30 -0
- package/src/bsonParser.test.ts +2 -2
- package/src/bsonParser.ts +16 -5
- package/src/{parserInvariant.ts → customInvariant.ts} +2 -2
- package/src/dalvikBytecodeParser/formatParsers.ts +421 -0
- package/src/dalvikBytecodeParser.ts +2074 -0
- package/src/dalvikExecutable.ts +220 -0
- package/src/dalvikExecutableParser/stringSyntaxParser.ts +145 -0
- package/src/dalvikExecutableParser/typeParsers.ts +65 -0
- package/src/dalvikExecutableParser/typedNumbers.ts +57 -0
- package/src/dalvikExecutableParser.test.ts +89 -0
- package/src/dalvikExecutableParser.test.ts.md +634 -0
- package/src/dalvikExecutableParser.test.ts.snap +0 -0
- package/src/dalvikExecutableParser.ts +2768 -0
- package/src/dalvikExecutableParserAgainstSmaliParser.test.ts +346 -0
- package/src/debugLogInputParser.ts +28 -0
- package/src/debugLogParser.ts +20 -4
- package/src/disjunctionParser.ts +10 -5
- package/src/elementParser.ts +3 -3
- package/src/elementTerminatedArrayParser.test.ts +99 -0
- package/src/elementTerminatedArrayParser.ts +31 -0
- package/src/elementTerminatedSequenceArrayParser.test.ts +54 -0
- package/src/elementTerminatedSequenceArrayParser.ts +52 -0
- package/src/elementTerminatedSequenceParser.test.ts +54 -0
- package/src/elementTerminatedSequenceParser.ts +43 -0
- package/src/endOfInputParser.ts +4 -4
- package/src/exactElementParser.ts +18 -12
- package/src/exactSequenceParser.ts +24 -3
- package/src/fetchCid.ts +125 -0
- package/src/fixedLengthSequenceParser.test.ts +77 -0
- package/src/fixedLengthSequenceParser.ts +28 -1
- package/src/hasExecutable.ts +11 -0
- package/src/highResolutionTimer.ts +49 -0
- package/src/index.ts +15 -2
- package/src/inputReader.test.ts +216 -7
- package/src/inputReader.ts +80 -5
- package/src/inputReaderState.ts +33 -0
- package/src/inspect.ts +9 -0
- package/src/javaKeyStore.ts +0 -0
- package/src/javaKeyStoreParser.test.ts +22 -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 +23 -34
- package/src/leb128Parser.test.ts +171 -0
- package/src/leb128Parser.ts +125 -0
- package/src/listParser.ts +6 -6
- package/src/lookaheadParser.ts +19 -0
- package/src/negativeLookaheadParser.test.ts +53 -0
- package/src/negativeLookaheadParser.ts +36 -0
- package/src/nonEmptyArrayParser.test.ts +20 -0
- package/src/nonEmptyArrayParser.ts +44 -0
- package/src/optionalParser.ts +4 -3
- package/src/parser.test.ts +148 -27
- package/src/parser.test.ts.md +21 -21
- package/src/parser.test.ts.snap +0 -0
- package/src/parser.ts +153 -49
- package/src/parserAccessorParser.ts +12 -2
- package/src/parserConsumedSequenceParser.ts +29 -0
- package/src/parserContext.test.ts +38 -7
- package/src/parserContext.ts +127 -51
- package/src/parserCreatorCompose.ts +25 -7
- package/src/parserError.ts +9 -6
- package/src/parserImplementationInvariant.ts +2 -2
- package/src/parserInputCompanion.ts +102 -0
- package/src/promiseCompose.ts +17 -3
- package/src/promiseSettled.ts +6 -0
- package/src/quantifierParser.ts +25 -0
- package/src/separatedArrayParser.test.ts +34 -0
- package/src/separatedArrayParser.ts +55 -0
- package/src/sequenceBuffer.test.ts +72 -2
- package/src/sequenceBuffer.ts +93 -7
- package/src/sequenceTerminatedSequenceParser.test.ts +60 -0
- package/src/sequenceTerminatedSequenceParser.ts +62 -0
- package/src/sequenceUnparser.ts +9 -0
- package/src/skipParser.ts +7 -5
- package/src/skipToParser.ts +16 -0
- package/src/sliceBoundedParser.test.ts +45 -3
- package/src/sliceBoundedParser.ts +21 -3
- package/src/smali.ts +24 -0
- package/src/smaliParser.test.ts +132 -0
- package/src/smaliParser.test.ts.md +2320 -0
- package/src/smaliParser.test.ts.snap +0 -0
- package/src/smaliParser.ts +1166 -0
- package/src/terminatedArrayParser.test.ts +258 -0
- package/src/terminatedArrayParser.ts +111 -6
- package/src/toAsyncIterable.ts +7 -0
- package/src/toAsyncIterator.ts +48 -0
- package/src/tupleParser.ts +8 -5
- package/src/uint8Array.ts +10 -0
- package/src/unionParser.test.ts +79 -0
- package/src/unionParser.ts +44 -16
- 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 +223 -146
- package/src/zipUnparser.test.ts +119 -0
- package/src/zipUnparser.ts +300 -0
- package/build/apk.d.ts +0 -13
- package/build/apkParser.d.ts +0 -3
- package/build/apkParser.js +0 -135
- package/build/arbitraryDosDate.d.ts +0 -2
- package/build/arbitraryDosDate.js +0 -8
- package/build/arbitraryZipEntry.d.ts +0 -3
- package/build/arbitraryZipEntry.js +0 -26
- package/build/createDisjunctionParser.d.ts +0 -2
- package/build/createDisjunctionParser.js +0 -47
- package/build/createExactParser.d.ts +0 -2
- package/build/createExactParser.js +0 -12
- package/build/createSequentialUnionParser.d.ts +0 -2
- package/build/createSequentialUnionParser.js +0 -69
- package/build/fixedLengthChunkParser.d.ts +0 -2
- package/build/fixedLengthChunkParser.js +0 -12
- package/build/fixedLengthParser.d.ts +0 -2
- package/build/fixedLengthParser.js +0 -12
- package/build/inputChunkBuffer.d.ts +0 -15
- package/build/inputChunkBuffer.js +0 -40
- package/build/inputChunkBuffer.test.js +0 -34
- package/build/inputCompanion.d.ts +0 -18
- package/build/inputCompanion.js +0 -28
- package/build/invariantDefined.d.ts +0 -1
- package/build/invariantDefined.js +0 -5
- package/build/invariantIdentity.d.ts +0 -3
- package/build/invariantIdentity.js +0 -5
- package/build/jsonParser2.d.ts +0 -3
- package/build/jsonParser2.js +0 -52
- package/build/jsonParser2.test.js +0 -22
- package/build/negativeLookahead.js +0 -20
- package/build/parserCompose.d.ts +0 -3
- package/build/parserCompose.js +0 -7
- package/build/parserImplementationInvariantInvariant.d.ts +0 -3
- package/build/parserImplementationInvariantInvariant.js +0 -15
- package/build/promiseFish.d.ts +0 -1
- package/build/promiseFish.js +0 -3
- package/build/sequenceParser.d.ts +0 -3
- package/build/sequenceParser.js +0 -10
- package/build/terminatedSequenceParser.d.ts +0 -2
- package/build/terminatedSequenceParser.js +0 -24
- package/build/zipEntry.d.ts +0 -28
- package/build/zipFile.d.ts +0 -32
- package/build/zipFileEntry.d.ts +0 -6
- package/src/apk.ts +0 -16
- package/src/apkParser.test.ts.md +0 -268
- package/src/apkParser.test.ts.snap +0 -0
- package/src/apkParser.ts +0 -327
- package/src/inputCompanion.ts +0 -43
- package/src/invariantDefined.ts +0 -6
- package/src/invariantIdentity.ts +0 -8
- package/src/negativeLookahead.ts +0 -26
- /package/build/{apk.js → androidPackage.js} +0 -0
- /package/build/{apkParser.test.d.ts → androidPackageParser.test.d.ts} +0 -0
- /package/build/{arbitraryDosPermissions.d.ts → androidPackageUnparser.test.d.ts} +0 -0
- /package/build/{arbitraryDosPermissions.js → dalvikExecutableParser.test.d.ts} +0 -0
- /package/build/{inputChunkBuffer.test.d.ts → dalvikExecutableParserAgainstSmaliParser.test.d.ts} +0 -0
- /package/build/{jsonParser2.test.d.ts → elementTerminatedArrayParser.test.d.ts} +0 -0
- /package/build/{parserParsingInvariant.d.ts → elementTerminatedSequenceArrayParser.test.d.ts} +0 -0
- /package/build/{parserParsingInvariant.js → elementTerminatedSequenceParser.test.d.ts} +0 -0
- /package/build/{zipEntry.js → fixedLengthSequenceParser.test.d.ts} +0 -0
- /package/build/{zipFile.js → javaKeyStore.d.ts} +0 -0
- /package/build/{zipFileEntry.js → javaKeyStore.js} +0 -0
package/build/listParser.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { createNegativeLookaheadParser } from
|
|
2
|
-
import { createParserAccessorParser } from
|
|
3
|
-
import { promiseCompose } from
|
|
4
|
-
import { createTupleParser } from
|
|
5
|
-
import { createUnionParser } from
|
|
1
|
+
import { createNegativeLookaheadParser } from './negativeLookaheadParser.js';
|
|
2
|
+
import { createParserAccessorParser } from './parserAccessorParser.js';
|
|
3
|
+
import { promiseCompose } from './promiseCompose.js';
|
|
4
|
+
import { createTupleParser } from './tupleParser.js';
|
|
5
|
+
import { createUnionParser } from './unionParser.js';
|
|
6
6
|
class Nil {
|
|
7
7
|
}
|
|
8
8
|
class Cons {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { getParserName, setParserName } from './parser.js';
|
|
2
|
+
export const createLookaheadParser = (childParser) => {
|
|
3
|
+
const lookaheadParser = async (parserContext) => {
|
|
4
|
+
const childParserContext = parserContext.lookahead();
|
|
5
|
+
try {
|
|
6
|
+
return await childParser(childParserContext);
|
|
7
|
+
}
|
|
8
|
+
finally {
|
|
9
|
+
childParserContext.dispose();
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
setParserName(lookaheadParser, `(?=${getParserName(childParser)})`);
|
|
13
|
+
return lookaheadParser;
|
|
14
|
+
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Parser } from
|
|
1
|
+
import { type Parser } from './parser.js';
|
|
2
2
|
export declare const createNegativeLookaheadParser: <Sequence>(childParser: Parser<unknown, Sequence>) => Parser<void, Sequence>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { getParserName, setParserName } from './parser.js';
|
|
2
|
+
import { ParserParsingFailedError } from './parserError.js';
|
|
3
|
+
export const createNegativeLookaheadParser = (childParser) => {
|
|
4
|
+
const negativeLookaheadParser = async (parserContext) => {
|
|
5
|
+
const childParserContext = parserContext.lookahead();
|
|
6
|
+
let childParserSuccess;
|
|
7
|
+
try {
|
|
8
|
+
await childParser(childParserContext);
|
|
9
|
+
childParserSuccess = true;
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
if (!(error instanceof ParserParsingFailedError)) {
|
|
13
|
+
throw error;
|
|
14
|
+
}
|
|
15
|
+
childParserSuccess = false;
|
|
16
|
+
}
|
|
17
|
+
finally {
|
|
18
|
+
childParserContext.dispose();
|
|
19
|
+
}
|
|
20
|
+
parserContext.invariant(!childParserSuccess, 'Negative lookahead assertion failed for child parser %s.', getParserName(childParser));
|
|
21
|
+
};
|
|
22
|
+
setParserName(negativeLookaheadParser, `(?!${getParserName(childParser)})`);
|
|
23
|
+
return negativeLookaheadParser;
|
|
24
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as fc from 'fast-check';
|
|
2
|
+
import { testProp } from '@fast-check/ava';
|
|
3
|
+
import { createNegativeLookaheadParser } from './negativeLookaheadParser.js';
|
|
4
|
+
import { createExactSequenceParser } from './exactSequenceParser.js';
|
|
5
|
+
import { runParser } from './parser.js';
|
|
6
|
+
import { stringParserInputCompanion } from './parserInputCompanion.js';
|
|
7
|
+
import { createTupleParser } from './tupleParser.js';
|
|
8
|
+
import { ParserParsingFailedError } from './parserError.js';
|
|
9
|
+
testProp('negativeLookaheadParser', [
|
|
10
|
+
fc.tuple(fc.string({
|
|
11
|
+
minLength: 1,
|
|
12
|
+
}), fc.string({
|
|
13
|
+
minLength: 1,
|
|
14
|
+
})).filter(([a, b]) => !a.startsWith(b))
|
|
15
|
+
], async (t, [stringA, stringB]) => {
|
|
16
|
+
const result = await runParser(createTupleParser([
|
|
17
|
+
createNegativeLookaheadParser(createExactSequenceParser(stringB)),
|
|
18
|
+
createExactSequenceParser(stringA + stringB),
|
|
19
|
+
]), stringA + stringB, stringParserInputCompanion);
|
|
20
|
+
t.deepEqual(result, [undefined, stringA + stringB]);
|
|
21
|
+
await t.throwsAsync(() => runParser(createTupleParser([
|
|
22
|
+
createNegativeLookaheadParser(createExactSequenceParser(stringA)),
|
|
23
|
+
createExactSequenceParser(stringA + stringB),
|
|
24
|
+
]), stringA + stringB, stringParserInputCompanion), {
|
|
25
|
+
instanceOf: ParserParsingFailedError,
|
|
26
|
+
message: /lookahead/,
|
|
27
|
+
});
|
|
28
|
+
}, {
|
|
29
|
+
verbose: true,
|
|
30
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { getParserName, setParserName } from './parser.js';
|
|
2
|
+
import { ParserParsingFailedError } from './parserError.js';
|
|
3
|
+
export const createNonEmptyArrayParser = (elementParser) => {
|
|
4
|
+
const nonEmptyArrayParser = async (parserContext) => {
|
|
5
|
+
const elements = [];
|
|
6
|
+
while (true) {
|
|
7
|
+
const elementParserContext = parserContext.lookahead();
|
|
8
|
+
const initialPosition = elementParserContext.position;
|
|
9
|
+
try {
|
|
10
|
+
const element = await elementParser(elementParserContext);
|
|
11
|
+
if (elementParserContext.position === initialPosition) {
|
|
12
|
+
break;
|
|
13
|
+
}
|
|
14
|
+
elements.push(element);
|
|
15
|
+
elementParserContext.unlookahead();
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
if (error instanceof ParserParsingFailedError) {
|
|
19
|
+
break;
|
|
20
|
+
}
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
finally {
|
|
24
|
+
elementParserContext.dispose();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
parserContext.invariant(elements.length > 0, 'Expected elementParser (%s) to match at least once', getParserName(elementParser, 'anonymousNonEmptyArrayChild'));
|
|
28
|
+
return elements;
|
|
29
|
+
};
|
|
30
|
+
setParserName(nonEmptyArrayParser, getParserName(elementParser, 'anonymousNonEmptyArrayChild') + '+');
|
|
31
|
+
return nonEmptyArrayParser;
|
|
32
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import { createNonEmptyArrayParser } from './nonEmptyArrayParser.js';
|
|
3
|
+
import { runParser } from './parser.js';
|
|
4
|
+
import { stringParserInputCompanion } from './parserInputCompanion.js';
|
|
5
|
+
import { createExactElementParser } from './exactElementParser.js';
|
|
6
|
+
test('empty array does not match', async (t) => {
|
|
7
|
+
const parser = createNonEmptyArrayParser(createExactElementParser('0'));
|
|
8
|
+
await t.throwsAsync(() => runParser(parser, '', stringParserInputCompanion), {
|
|
9
|
+
message: /Expected .* to match at least once/,
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
test('non-empty array matches', async (t) => {
|
|
13
|
+
const parser = createNonEmptyArrayParser(createExactElementParser('0'));
|
|
14
|
+
const result = await runParser(parser, '0', stringParserInputCompanion);
|
|
15
|
+
t.deepEqual(result, ['0']);
|
|
16
|
+
});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Parser } from
|
|
1
|
+
import { type Parser } from './parser.js';
|
|
2
2
|
export declare const createOptionalParser: <Output, Sequence>(childParser: Parser<Output, Sequence>) => Parser<undefined | Output, Sequence>;
|
package/build/optionalParser.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { getParserName, setParserName } from
|
|
2
|
-
import { ParserParsingFailedError } from
|
|
1
|
+
import { getParserName, setParserName } from './parser.js';
|
|
2
|
+
import { ParserParsingFailedError } from './parserError.js';
|
|
3
3
|
export const createOptionalParser = (childParser) => {
|
|
4
4
|
const optionalParser = async (parserContext) => {
|
|
5
5
|
const childParserContext = parserContext.lookahead();
|
package/build/parser.d.ts
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Class } from 'type-fest';
|
|
2
|
+
import { type ParserInputCompanion } from './parserInputCompanion.js';
|
|
2
3
|
import { type ParserContext } from './parserContext.js';
|
|
3
|
-
import { DeriveSequenceElement } from './sequence.js';
|
|
4
|
-
export type Parser<Output, Sequence, Element = DeriveSequenceElement<Sequence>> = (parserContext: ParserContext<Sequence, Element>) => Promise<Output>;
|
|
4
|
+
import { type DeriveSequenceElement } from './sequence.js';
|
|
5
|
+
export type Parser<Output, Sequence, Element = DeriveSequenceElement<Sequence>> = (parserContext: ParserContext<Sequence, Element>) => Output | Promise<Output>;
|
|
5
6
|
export declare function getParserName(parser: Parser<any, any, any>, default_?: string): string;
|
|
6
7
|
export declare function setParserName<Output, Sequence, Element = DeriveSequenceElement<Sequence>>(parser: Parser<Output, Sequence, Element>, name: string): Parser<Output, Sequence, Element>;
|
|
8
|
+
export declare function cloneParser<Output, Sequence, Element = DeriveSequenceElement<Sequence>>(parser: Parser<Output, Sequence, Element>): Parser<Output, Sequence, Element>;
|
|
7
9
|
export type RunParserOptions<Output, Sequence, Element = DeriveSequenceElement<Sequence>> = {
|
|
8
10
|
errorJoinMode?: 'none' | 'deepest' | 'furthest' | 'all';
|
|
11
|
+
parserContextClass?: Class<ParserContext<Sequence, Element>>;
|
|
9
12
|
};
|
|
10
|
-
export
|
|
13
|
+
export type RunParserWithRemainingInputResult<Output, Sequence, Element = DeriveSequenceElement<Sequence>> = {
|
|
14
|
+
output: Output;
|
|
15
|
+
position: number;
|
|
16
|
+
remainingInput: undefined | AsyncIterable<Sequence>;
|
|
17
|
+
};
|
|
18
|
+
export declare function runParserWithRemainingInput<Output, Sequence, Element = DeriveSequenceElement<Sequence>>(parser: Parser<Output, Sequence, Element>, input: AsyncIterator<Sequence> | AsyncIterable<Sequence> | Iterable<Sequence> | Sequence, parserInputCompanion: ParserInputCompanion<Sequence, Element>, options?: RunParserOptions<Output, Sequence, Element>): Promise<RunParserWithRemainingInputResult<Output, Sequence, Element>>;
|
|
19
|
+
export declare function runParser<Output, Sequence, Element = DeriveSequenceElement<Sequence>>(parser: Parser<Output, Sequence, Element>, input: AsyncIterator<Sequence> | AsyncIterable<Sequence> | Iterable<Sequence> | Sequence, parserInputCompanion: ParserInputCompanion<Sequence, Element>, options?: RunParserOptions<Output, Sequence, Element>): Promise<Output>;
|
package/build/parser.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import invariant from 'invariant';
|
|
2
1
|
import { InputReaderImplementation } from './inputReader.js';
|
|
3
2
|
import { ParserContextImplementation } from './parserContext.js';
|
|
3
|
+
import { ParserError, ParserUnexpectedRemainingInputError } from './parserError.js';
|
|
4
|
+
import { toAsyncIterator } from './toAsyncIterator.js';
|
|
5
|
+
import { inputReaderStateCompanion } from './inputReaderState.js';
|
|
4
6
|
export function getParserName(parser, default_ = 'anonymous') {
|
|
5
7
|
return parser.name || default_;
|
|
6
8
|
}
|
|
@@ -10,44 +12,77 @@ export function setParserName(parser, name) {
|
|
|
10
12
|
});
|
|
11
13
|
return parser;
|
|
12
14
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
function isIterator(value) {
|
|
20
|
-
return value && typeof value.next === 'function';
|
|
21
|
-
}
|
|
22
|
-
function iteratorToAsyncIterator(iterator) {
|
|
23
|
-
return {
|
|
24
|
-
next: async () => iterator.next(),
|
|
15
|
+
const originalParserByClone = new WeakMap();
|
|
16
|
+
export function cloneParser(parser) {
|
|
17
|
+
const originalParser = originalParserByClone.get(parser) ?? parser;
|
|
18
|
+
const clone = (parserContext) => {
|
|
19
|
+
return originalParser(parserContext);
|
|
25
20
|
};
|
|
21
|
+
setParserName(clone, getParserName(parser));
|
|
22
|
+
originalParserByClone.set(clone, originalParser);
|
|
23
|
+
return clone;
|
|
26
24
|
}
|
|
27
|
-
function
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return (async function* () {
|
|
31
|
-
yield value;
|
|
32
|
-
})();
|
|
33
|
-
}
|
|
34
|
-
if (isAsyncIterable(value)) {
|
|
35
|
-
return value[Symbol.asyncIterator]();
|
|
36
|
-
}
|
|
37
|
-
if (isIterable(value)) {
|
|
38
|
-
return iteratorToAsyncIterator(value[Symbol.iterator]());
|
|
25
|
+
async function withEnrichedParserError(parserContext, inputReader, f) {
|
|
26
|
+
try {
|
|
27
|
+
return await f();
|
|
39
28
|
}
|
|
40
|
-
|
|
41
|
-
|
|
29
|
+
catch (error) {
|
|
30
|
+
if (error instanceof ParserError) {
|
|
31
|
+
if (error.position === undefined) {
|
|
32
|
+
error.position = parserContext.position;
|
|
33
|
+
}
|
|
34
|
+
if (error.inputReaderSate === undefined) {
|
|
35
|
+
error.inputReaderSate = inputReader.toInputReaderState();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
throw error;
|
|
42
39
|
}
|
|
43
|
-
invariant(false, 'Value must be an async iterator, async iterable, iterable or iterator got %s.', value);
|
|
44
40
|
}
|
|
45
|
-
|
|
41
|
+
function runParserInternal(parser, input, parserInputCompanion, options = {}) {
|
|
46
42
|
const inputAsyncIterator = toAsyncIterator(input);
|
|
47
|
-
const inputReader = new InputReaderImplementation(
|
|
48
|
-
const
|
|
43
|
+
const inputReader = new InputReaderImplementation(parserInputCompanion, inputAsyncIterator);
|
|
44
|
+
const ParserContext = options.parserContextClass ?? ParserContextImplementation;
|
|
45
|
+
const parserContext = new ParserContext(parserInputCompanion, inputReader, undefined, {
|
|
49
46
|
...options,
|
|
50
47
|
debugName: 'root',
|
|
51
48
|
});
|
|
52
|
-
|
|
49
|
+
const outputPromise = (async () => {
|
|
50
|
+
try {
|
|
51
|
+
return await parser(parserContext);
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
await parserContext.peek(0);
|
|
55
|
+
}
|
|
56
|
+
})();
|
|
57
|
+
return {
|
|
58
|
+
outputPromise,
|
|
59
|
+
parserContext,
|
|
60
|
+
inputReader,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export async function runParserWithRemainingInput(parser, input, parserInputCompanion, options = {}) {
|
|
64
|
+
const { outputPromise, parserContext, inputReader, } = runParserInternal(parser, input, parserInputCompanion, options);
|
|
65
|
+
return await withEnrichedParserError(parserContext, inputReader, async () => {
|
|
66
|
+
const output = await outputPromise;
|
|
67
|
+
const inputReaderState = inputReader.toInputReaderState();
|
|
68
|
+
const remainingInput = (inputReaderStateCompanion.isDone(inputReaderState)
|
|
69
|
+
? undefined
|
|
70
|
+
: inputReaderStateCompanion.toRemainingInputAsyncIterator(inputReaderState));
|
|
71
|
+
return {
|
|
72
|
+
output,
|
|
73
|
+
position: parserContext.position,
|
|
74
|
+
remainingInput,
|
|
75
|
+
};
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
export async function runParser(parser, input, parserInputCompanion, options = {}) {
|
|
79
|
+
const { outputPromise, parserContext, inputReader, } = runParserInternal(parser, input, parserInputCompanion, options);
|
|
80
|
+
return await withEnrichedParserError(parserContext, inputReader, async () => {
|
|
81
|
+
const output = await outputPromise;
|
|
82
|
+
const inputReaderState = inputReader.toInputReaderState();
|
|
83
|
+
if (!inputReaderStateCompanion.isDone(inputReaderState)) {
|
|
84
|
+
throw new ParserUnexpectedRemainingInputError('Unexpected remaining input', 0, parserContext.position);
|
|
85
|
+
}
|
|
86
|
+
return output;
|
|
87
|
+
});
|
|
53
88
|
}
|
package/build/parser.test.js
CHANGED
|
@@ -1,31 +1,32 @@
|
|
|
1
1
|
import test from 'ava';
|
|
2
|
+
import invariant from 'invariant';
|
|
2
3
|
import { createUnionParser } from './unionParser.js';
|
|
3
|
-
import { runParser } from './parser.js';
|
|
4
|
-
import {
|
|
5
|
-
import { ParserParsingInvariantError, ParserParsingJoinAllError, ParserParsingJoinDeepestError, ParserParsingJoinError, ParserParsingJoinFurthestError, ParserParsingJoinNoneError } from './parserError.js';
|
|
4
|
+
import { runParser, runParserWithRemainingInput } from './parser.js';
|
|
5
|
+
import { stringParserInputCompanion, uint8ArrayParserInputCompanion } from './parserInputCompanion.js';
|
|
6
|
+
import { ParserError, ParserParsingInvariantError, ParserParsingJoinAllError, ParserParsingJoinDeepestError, ParserParsingJoinError, ParserParsingJoinFurthestError, ParserParsingJoinNoneError, ParserUnexpectedRemainingInputError, } from './parserError.js';
|
|
6
7
|
import { createTupleParser } from './tupleParser.js';
|
|
7
8
|
import { promiseCompose } from './promiseCompose.js';
|
|
8
9
|
import { createDisjunctionParser } from './disjunctionParser.js';
|
|
9
|
-
import
|
|
10
|
-
import { createExactSequenceParser } from './exactSequenceParser.js';
|
|
10
|
+
import { createExactSequenceNaiveParser } from './exactSequenceParser.js';
|
|
11
11
|
import { createArrayParser } from './arrayParser.js';
|
|
12
12
|
import { createElementParser } from './elementParser.js';
|
|
13
|
+
import { toAsyncIterable } from './toAsyncIterable.js';
|
|
13
14
|
const aUnionParser = createUnionParser([
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
createExactSequenceNaiveParser('1'),
|
|
16
|
+
createExactSequenceNaiveParser('aa'),
|
|
17
|
+
createExactSequenceNaiveParser('AAA'),
|
|
17
18
|
]);
|
|
18
19
|
const abDisjunctionParser = createDisjunctionParser([
|
|
19
20
|
aUnionParser,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
createExactSequenceNaiveParser('2'),
|
|
22
|
+
createExactSequenceNaiveParser('bb'),
|
|
23
|
+
createExactSequenceNaiveParser('BBB'),
|
|
23
24
|
]);
|
|
24
25
|
const abcUnionParser = createUnionParser([
|
|
25
26
|
abDisjunctionParser,
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
createExactSequenceNaiveParser('final_3'),
|
|
28
|
+
createExactSequenceNaiveParser('final_cc'),
|
|
29
|
+
createExactSequenceNaiveParser('final_CCC'),
|
|
29
30
|
]);
|
|
30
31
|
const sampleParser = promiseCompose(createTupleParser([
|
|
31
32
|
aUnionParser,
|
|
@@ -35,6 +36,13 @@ const sampleParser = promiseCompose(createTupleParser([
|
|
|
35
36
|
async function* asyncIteratorFromString(string) {
|
|
36
37
|
yield string;
|
|
37
38
|
}
|
|
39
|
+
async function stringFromAsyncIterable(asyncIterable) {
|
|
40
|
+
let string = '';
|
|
41
|
+
for await (const chunk of asyncIterable) {
|
|
42
|
+
string += chunk;
|
|
43
|
+
}
|
|
44
|
+
return string;
|
|
45
|
+
}
|
|
38
46
|
function sortChildErrors(error) {
|
|
39
47
|
error.childErrors.sort((a, b) => a.message.localeCompare(b.message));
|
|
40
48
|
for (const childError of error.childErrors) {
|
|
@@ -44,23 +52,23 @@ function sortChildErrors(error) {
|
|
|
44
52
|
}
|
|
45
53
|
}
|
|
46
54
|
function removeStackLocations(errorStack) {
|
|
47
|
-
return errorStack.
|
|
55
|
+
return errorStack.replaceAll(/((at [^\n]+)[\s\n]+)+(at [^\n]+)/g, 'at [LOCATIONS]');
|
|
48
56
|
}
|
|
49
57
|
test('errorJoinMode: none', async (t) => {
|
|
50
|
-
const error = await t.throwsAsync(runParser(sampleParser, asyncIteratorFromString('1bbfinal_CC!'),
|
|
58
|
+
const error = await t.throwsAsync(runParser(sampleParser, asyncIteratorFromString('1bbfinal_CC!'), stringParserInputCompanion, {
|
|
51
59
|
errorJoinMode: 'none',
|
|
52
60
|
}), {
|
|
53
|
-
instanceOf: ParserParsingJoinNoneError
|
|
61
|
+
instanceOf: ParserParsingJoinNoneError,
|
|
54
62
|
});
|
|
55
63
|
t.is(error.position, 12);
|
|
56
64
|
t.deepEqual(error.childErrors, []);
|
|
57
65
|
t.snapshot(removeStackLocations(error.stack));
|
|
58
66
|
});
|
|
59
67
|
test('errorJoinMode: all', async (t) => {
|
|
60
|
-
const error = await t.throwsAsync(runParser(sampleParser, asyncIteratorFromString('1bbfinal_CC!'),
|
|
68
|
+
const error = await t.throwsAsync(runParser(sampleParser, asyncIteratorFromString('1bbfinal_CC!'), stringParserInputCompanion, {
|
|
61
69
|
errorJoinMode: 'all',
|
|
62
70
|
}), {
|
|
63
|
-
instanceOf: ParserParsingJoinAllError
|
|
71
|
+
instanceOf: ParserParsingJoinAllError,
|
|
64
72
|
});
|
|
65
73
|
sortChildErrors(error);
|
|
66
74
|
t.snapshot(removeStackLocations(error.stack));
|
|
@@ -79,7 +87,7 @@ test('errorJoinMode: all', async (t) => {
|
|
|
79
87
|
t.is(error3.position, 4, 'error3.position');
|
|
80
88
|
});
|
|
81
89
|
test('errorJoinMode: deepest', async (t) => {
|
|
82
|
-
const error = await t.throwsAsync(runParser(sampleParser, asyncIteratorFromString('1bbfinal_CC!'),
|
|
90
|
+
const error = await t.throwsAsync(runParser(sampleParser, asyncIteratorFromString('1bbfinal_CC!'), stringParserInputCompanion, {
|
|
83
91
|
errorJoinMode: 'deepest',
|
|
84
92
|
}), {
|
|
85
93
|
instanceOf: ParserParsingJoinDeepestError,
|
|
@@ -101,7 +109,7 @@ test('errorJoinMode: deepest', async (t) => {
|
|
|
101
109
|
t.is(error3.position, 4);
|
|
102
110
|
});
|
|
103
111
|
test('errorJoinMode: furthest', async (t) => {
|
|
104
|
-
const error = await t.throwsAsync(runParser(sampleParser, asyncIteratorFromString('1bbfinal_CC!'),
|
|
112
|
+
const error = await t.throwsAsync(runParser(sampleParser, asyncIteratorFromString('1bbfinal_CC!'), stringParserInputCompanion, {
|
|
105
113
|
errorJoinMode: 'furthest',
|
|
106
114
|
}), {
|
|
107
115
|
instanceOf: ParserParsingJoinFurthestError,
|
|
@@ -114,13 +122,72 @@ test('errorJoinMode: furthest', async (t) => {
|
|
|
114
122
|
invariant(error1 instanceof ParserParsingInvariantError, 'error1 instanceof ParserParsingInvariantError');
|
|
115
123
|
t.is(error1.position, 12);
|
|
116
124
|
});
|
|
117
|
-
test('throws on
|
|
125
|
+
test('throws on parserInputCompanion type mismatch', async (t) => {
|
|
118
126
|
const anythingParser = createArrayParser(createElementParser());
|
|
119
|
-
await runParser(anythingParser, asyncIteratorFromString('anything'),
|
|
120
|
-
await runParser(anythingParser, 'anything',
|
|
121
|
-
await runParser(anythingParser, Buffer.from('anything'),
|
|
122
|
-
await runParser(anythingParser, new Uint8Array([1, 2, 3]),
|
|
123
|
-
await t.throwsAsync(runParser(anythingParser, asyncIteratorFromString('anything'),
|
|
127
|
+
await runParser(anythingParser, asyncIteratorFromString('anything'), stringParserInputCompanion);
|
|
128
|
+
await runParser(anythingParser, 'anything', stringParserInputCompanion);
|
|
129
|
+
await runParser(anythingParser, Buffer.from('anything'), uint8ArrayParserInputCompanion);
|
|
130
|
+
await runParser(anythingParser, new Uint8Array([1, 2, 3]), uint8ArrayParserInputCompanion);
|
|
131
|
+
await t.throwsAsync(runParser(anythingParser, asyncIteratorFromString('anything'), uint8ArrayParserInputCompanion), {
|
|
124
132
|
message: /input companion/,
|
|
125
133
|
});
|
|
126
134
|
});
|
|
135
|
+
test('thrown error has input reader state', async (t) => {
|
|
136
|
+
const error = await t.throwsAsync(runParser(createTupleParser([
|
|
137
|
+
createExactSequenceNaiveParser('foo'),
|
|
138
|
+
createExactSequenceNaiveParser('bar'),
|
|
139
|
+
]), (async function* () {
|
|
140
|
+
yield 'foo';
|
|
141
|
+
yield 'qux';
|
|
142
|
+
yield 'bar';
|
|
143
|
+
})(), stringParserInputCompanion), {
|
|
144
|
+
instanceOf: ParserError,
|
|
145
|
+
});
|
|
146
|
+
t.is(error.position, 4);
|
|
147
|
+
invariant(error.inputReaderSate, 'error.inputReaderSate');
|
|
148
|
+
const { consumedBufferedSequences, unconsumedBufferedSequences, unbufferedSequences, position, ...inputReaderStateRest } = error.inputReaderSate;
|
|
149
|
+
t.is(position, 4);
|
|
150
|
+
t.deepEqual(inputReaderStateRest, {});
|
|
151
|
+
const unbufferedSequencesArray = [];
|
|
152
|
+
if (unbufferedSequences) {
|
|
153
|
+
for await (const sequence of toAsyncIterable(unbufferedSequences)) {
|
|
154
|
+
unbufferedSequencesArray.push(sequence);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
t.deepEqual(consumedBufferedSequences, ['q']);
|
|
158
|
+
t.deepEqual(unconsumedBufferedSequences, ['ux']);
|
|
159
|
+
t.deepEqual(unbufferedSequencesArray, ['bar']);
|
|
160
|
+
});
|
|
161
|
+
test('runParser throws with remaining input', async (t) => {
|
|
162
|
+
const parser = createExactSequenceNaiveParser('foo');
|
|
163
|
+
const error = await t.throwsAsync(() => runParser(parser, 'foobar', stringParserInputCompanion), {
|
|
164
|
+
instanceOf: ParserUnexpectedRemainingInputError,
|
|
165
|
+
message: /remaining input/,
|
|
166
|
+
});
|
|
167
|
+
t.is(error.position, 3);
|
|
168
|
+
const { position, consumedBufferedSequences, unconsumedBufferedSequences, unbufferedSequences, ...inputReaderStateRest } = error.inputReaderSate;
|
|
169
|
+
t.deepEqual(inputReaderStateRest, {});
|
|
170
|
+
t.is(position, 3);
|
|
171
|
+
t.deepEqual(consumedBufferedSequences, ['foo']);
|
|
172
|
+
t.deepEqual(unconsumedBufferedSequences, ['bar']);
|
|
173
|
+
t.truthy(unbufferedSequences);
|
|
174
|
+
});
|
|
175
|
+
test('runParser does not throw without remaining input', async (t) => {
|
|
176
|
+
const parser = createExactSequenceNaiveParser('foo');
|
|
177
|
+
const output = await runParser(parser, 'foo', stringParserInputCompanion);
|
|
178
|
+
t.deepEqual(output, 'foo');
|
|
179
|
+
});
|
|
180
|
+
test('runParserWithRemainingInput with remaining input', async (t) => {
|
|
181
|
+
const parser = createExactSequenceNaiveParser('foo');
|
|
182
|
+
const { output, remainingInput, position, ...resultRest } = await runParserWithRemainingInput(parser, 'foobar', stringParserInputCompanion);
|
|
183
|
+
t.deepEqual(resultRest, {});
|
|
184
|
+
t.deepEqual(output, 'foo');
|
|
185
|
+
t.deepEqual(await stringFromAsyncIterable(remainingInput), 'bar');
|
|
186
|
+
t.is(position, 3);
|
|
187
|
+
});
|
|
188
|
+
test('runParserWithRemainingInput without remaining input', async (t) => {
|
|
189
|
+
const parser = createExactSequenceNaiveParser('foo');
|
|
190
|
+
const { output, remainingInput } = await runParserWithRemainingInput(parser, 'foo', stringParserInputCompanion);
|
|
191
|
+
t.deepEqual(output, 'foo');
|
|
192
|
+
t.is(remainingInput, undefined);
|
|
193
|
+
});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Parser } from
|
|
1
|
+
import { type Parser } from './parser.js';
|
|
2
2
|
export declare const createParserAccessorParser: <Output, Sequence>(parserAccessor: () => Parser<Output, Sequence>) => Parser<Output, Sequence>;
|
|
@@ -1 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import { getParserName, setParserName } from './parser.js';
|
|
2
|
+
export const createParserAccessorParser = (parserAccessor) => {
|
|
3
|
+
const parserAccessorParser = async (parserContext) => {
|
|
4
|
+
const parser = parserAccessor();
|
|
5
|
+
setParserName(parserAccessorParser, `parserAccessorParser(${getParserName(parser, 'anonymousParserAccessor')})`);
|
|
6
|
+
return parser(parserContext);
|
|
7
|
+
};
|
|
8
|
+
return parserAccessorParser;
|
|
9
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { createFixedLengthSequenceParser } from "./fixedLengthSequenceParser.js";
|
|
2
|
+
import { getParserName, setParserName } from "./parser.js";
|
|
3
|
+
export const createParserConsumedSequenceParser = (childParser) => {
|
|
4
|
+
const parserConsumedSequenceParser = async (parserContext) => {
|
|
5
|
+
const initialPosition = parserContext.position;
|
|
6
|
+
const childParserContext = parserContext.lookahead();
|
|
7
|
+
let value;
|
|
8
|
+
let consumedLength;
|
|
9
|
+
try {
|
|
10
|
+
value = await childParser(childParserContext);
|
|
11
|
+
consumedLength = childParserContext.position - initialPosition;
|
|
12
|
+
}
|
|
13
|
+
finally {
|
|
14
|
+
childParserContext.dispose();
|
|
15
|
+
}
|
|
16
|
+
const consumedSequenceParser = createFixedLengthSequenceParser(consumedLength);
|
|
17
|
+
const consumedSequence = await consumedSequenceParser(parserContext);
|
|
18
|
+
return [value, consumedSequence];
|
|
19
|
+
};
|
|
20
|
+
setParserName(parserConsumedSequenceParser, `parserConsumedSequenceParser(${getParserName(childParser, 'anonymousParserConsumedSequenceParserChild')})`);
|
|
21
|
+
return parserConsumedSequenceParser;
|
|
22
|
+
};
|
package/build/parserContext.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type ParserInputCompanion } from './parserInputCompanion.js';
|
|
2
2
|
import { type InputReader } from './inputReader.js';
|
|
3
|
-
import { ParserParsingFailedError } from './parserError.js';
|
|
4
|
-
import { RunParserOptions } from './parser.js';
|
|
5
|
-
import { Falsy, ValueOrAccessor } from './
|
|
3
|
+
import { type ParserParsingFailedError } from './parserError.js';
|
|
4
|
+
import { type RunParserOptions } from './parser.js';
|
|
5
|
+
import { type Falsy, type ValueOrAccessor } from './customInvariant.js';
|
|
6
6
|
type LookaheadOptions = {
|
|
7
7
|
debugName?: string;
|
|
8
8
|
sliceEnd?: number;
|
|
@@ -10,12 +10,19 @@ type LookaheadOptions = {
|
|
|
10
10
|
type ParserContextOptions<Sequence, Element> = RunParserOptions<unknown, Sequence, Element> & LookaheadOptions;
|
|
11
11
|
export type ParserContext<Sequence, Element> = {
|
|
12
12
|
from(elements: Element[]): Sequence;
|
|
13
|
+
concat(sequences: Sequence[]): Sequence;
|
|
13
14
|
length(sequence: Sequence): number;
|
|
14
15
|
at(sequence: Sequence, index: number): Element | undefined;
|
|
16
|
+
subsequence(sequence: Sequence, start: number, end: number): Sequence;
|
|
17
|
+
indexOf(sequence: Sequence, element: Element, fromIndex?: number): number;
|
|
18
|
+
indexOfSubsequence(sequence: Sequence, subsequence: Sequence, fromIndex?: number): number;
|
|
19
|
+
equals(sequenceA: Sequence, sequenceB: Sequence): boolean;
|
|
15
20
|
get position(): number;
|
|
16
21
|
peek(offset: number): Promise<Element | undefined>;
|
|
22
|
+
peekSequence(start: number, end: number): Promise<Sequence | undefined>;
|
|
17
23
|
skip(offset: number): void;
|
|
18
24
|
read(offset: number): Promise<Element>;
|
|
25
|
+
readSequence(start: number, end: number): Promise<Sequence>;
|
|
19
26
|
lookahead(options?: LookaheadOptions): ParserContext<Sequence, Element>;
|
|
20
27
|
unlookahead(): void;
|
|
21
28
|
dispose(): void;
|
|
@@ -23,22 +30,29 @@ export type ParserContext<Sequence, Element> = {
|
|
|
23
30
|
invariantJoin<T>(value: T, childErrors: ParserParsingFailedError[], format: ValueOrAccessor<string | string[]>, ...formatArguments: any[]): Exclude<T, Falsy>;
|
|
24
31
|
};
|
|
25
32
|
export declare class ParserContextImplementation<Sequence, Element> implements ParserContext<Sequence, Element> {
|
|
26
|
-
private readonly
|
|
33
|
+
private readonly _parserInputCompanion;
|
|
27
34
|
private _inputReader;
|
|
28
35
|
private _parentParserContext;
|
|
29
36
|
private readonly _options;
|
|
30
37
|
private readonly _id;
|
|
31
38
|
private readonly _depth;
|
|
32
39
|
private _exclusiveChildParserContext;
|
|
33
|
-
constructor(
|
|
40
|
+
constructor(_parserInputCompanion: ParserInputCompanion<Sequence, Element>, _inputReader: InputReader<Sequence, Element>, _parentParserContext: ParserContextImplementation<Sequence, Element> | undefined, _options: ParserContextOptions<Sequence, Element>);
|
|
34
41
|
get [Symbol.toStringTag](): string;
|
|
35
42
|
from(elements: Element[]): Sequence;
|
|
43
|
+
concat(sequences: Sequence[]): Sequence;
|
|
36
44
|
length(sequence: Sequence): number;
|
|
37
45
|
at(sequence: Sequence, index: number): Element | undefined;
|
|
46
|
+
subsequence(sequence: Sequence, start: number, end: number): Sequence;
|
|
47
|
+
indexOf(sequence: Sequence, element: Element, fromIndex?: number): number;
|
|
48
|
+
indexOfSubsequence(sequence: Sequence, subsequence: Sequence, fromIndex?: number): number;
|
|
49
|
+
equals(sequenceA: Sequence, sequenceB: Sequence): boolean;
|
|
38
50
|
get position(): number;
|
|
39
51
|
peek(offset: number): Promise<Element | undefined>;
|
|
52
|
+
peekSequence(start: number, end: number): Promise<Sequence | undefined>;
|
|
40
53
|
skip(offset: number): void;
|
|
41
54
|
read(offset: number): Promise<Element>;
|
|
55
|
+
readSequence(start: number, end: number): Promise<Sequence>;
|
|
42
56
|
lookahead(options?: LookaheadOptions): ParserContext<Sequence, Element>;
|
|
43
57
|
unlookahead(): void;
|
|
44
58
|
dispose(): void;
|