@thomasfosterau/effect-parse 0.0.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +247 -230
- package/dist/Ascii.d.ts +32 -53
- package/dist/Ascii.d.ts.map +1 -1
- package/dist/Ascii.js +576 -571
- package/dist/Ascii.js.map +1 -1
- package/dist/Binary.d.ts +6 -29
- package/dist/Binary.d.ts.map +1 -1
- package/dist/Binary.js +129 -116
- package/dist/Binary.js.map +1 -1
- package/dist/Bits.d.ts +4 -2
- package/dist/Bits.d.ts.map +1 -1
- package/dist/Bits.js +121 -123
- package/dist/Bits.js.map +1 -1
- package/dist/Compiler.d.ts +39 -0
- package/dist/Compiler.d.ts.map +1 -0
- package/dist/Compiler.js +48 -0
- package/dist/Compiler.js.map +1 -0
- package/dist/Encoding.d.ts +29 -46
- package/dist/Encoding.d.ts.map +1 -1
- package/dist/Encoding.js +76 -75
- package/dist/Encoding.js.map +1 -1
- package/dist/Expression.d.ts +15 -49
- package/dist/Expression.d.ts.map +1 -1
- package/dist/Expression.js +143 -131
- package/dist/Expression.js.map +1 -1
- package/dist/Input.d.ts +206 -177
- package/dist/Input.d.ts.map +1 -1
- package/dist/Input.js +317 -299
- package/dist/Input.js.map +1 -1
- package/dist/Nom.d.ts +44 -84
- package/dist/Nom.d.ts.map +1 -1
- package/dist/Nom.js +423 -453
- package/dist/Nom.js.map +1 -1
- package/dist/ParseError.d.ts +54 -49
- package/dist/ParseError.d.ts.map +1 -1
- package/dist/ParseError.js +233 -275
- package/dist/ParseError.js.map +1 -1
- package/dist/Parser.d.ts +345 -313
- package/dist/Parser.d.ts.map +1 -1
- package/dist/Parser.js +2010 -1802
- package/dist/Parser.js.map +1 -1
- package/dist/ParserSchema.d.ts +8 -7
- package/dist/ParserSchema.d.ts.map +1 -1
- package/dist/ParserSchema.js +49 -49
- package/dist/ParserSchema.js.map +1 -1
- package/dist/ParserStream.d.ts +26 -20
- package/dist/ParserStream.d.ts.map +1 -1
- package/dist/ParserStream.js +267 -255
- package/dist/ParserStream.js.map +1 -1
- package/dist/Syntax.d.ts +401 -0
- package/dist/Syntax.d.ts.map +1 -0
- package/dist/Syntax.js +717 -0
- package/dist/Syntax.js.map +1 -0
- package/dist/Text.d.ts +98 -134
- package/dist/Text.d.ts.map +1 -1
- package/dist/Text.js +534 -496
- package/dist/Text.js.map +1 -1
- package/dist/Token.d.ts +60 -42
- package/dist/Token.d.ts.map +1 -1
- package/dist/Token.js +331 -265
- package/dist/Token.js.map +1 -1
- package/dist/index.d.ts +16 -17
- package/dist/index.js +16 -17
- package/dist/internal/compiler/closure.d.ts +14 -16
- package/dist/internal/compiler/closure.d.ts.map +1 -1
- package/dist/internal/compiler/closure.js +1458 -1637
- package/dist/internal/compiler/closure.js.map +1 -1
- package/dist/internal/compiler/entries.d.ts +11 -11
- package/dist/internal/compiler/entries.d.ts.map +1 -1
- package/dist/internal/compiler/entries.js +36 -26
- package/dist/internal/compiler/entries.js.map +1 -1
- package/dist/internal/compiler/first.d.ts +19 -19
- package/dist/internal/compiler/first.d.ts.map +1 -1
- package/dist/internal/compiler/first.js +251 -227
- package/dist/internal/compiler/first.js.map +1 -1
- package/dist/internal/compiler/jit.d.ts +6 -17
- package/dist/internal/compiler/jit.d.ts.map +1 -1
- package/dist/internal/compiler/jit.js +860 -988
- package/dist/internal/compiler/jit.js.map +1 -1
- package/dist/internal/compiler/registry.d.ts +20 -21
- package/dist/internal/compiler/registry.d.ts.map +1 -1
- package/dist/internal/compiler/registry.js +21 -41
- package/dist/internal/compiler/registry.js.map +1 -1
- package/dist/internal/compiler/sets.d.ts +9 -13
- package/dist/internal/compiler/sets.d.ts.map +1 -1
- package/dist/internal/compiler/sets.js +76 -73
- package/dist/internal/compiler/sets.js.map +1 -1
- package/dist/internal/entries.d.ts +3 -3
- package/dist/internal/entries.d.ts.map +1 -1
- package/dist/internal/entries.js +38 -30
- package/dist/internal/entries.js.map +1 -1
- package/dist/internal/node.d.ts +177 -173
- package/dist/internal/node.d.ts.map +1 -1
- package/dist/internal/node.js +77 -66
- package/dist/internal/node.js.map +1 -1
- package/dist/internal/numbers.d.ts +7 -8
- package/dist/internal/numbers.d.ts.map +1 -1
- package/dist/internal/numbers.js +246 -276
- package/dist/internal/numbers.js.map +1 -1
- package/dist/internal/resume.d.ts +6 -24
- package/dist/internal/resume.d.ts.map +1 -1
- package/dist/internal/resume.js +30 -29
- package/dist/internal/resume.js.map +1 -1
- package/dist/internal/run.d.ts +15 -0
- package/dist/internal/run.d.ts.map +1 -0
- package/dist/internal/run.js +36 -0
- package/dist/internal/run.js.map +1 -0
- package/dist/internal/stack.d.ts +16 -0
- package/dist/internal/stack.d.ts.map +1 -0
- package/dist/internal/stack.js +26 -0
- package/dist/internal/stack.js.map +1 -0
- package/dist/internal/syntax.d.ts +146 -0
- package/dist/internal/syntax.d.ts.map +1 -0
- package/dist/internal/syntax.js +305 -0
- package/dist/internal/syntax.js.map +1 -0
- package/dist/internal/text.d.ts +10 -2
- package/dist/internal/text.d.ts.map +1 -1
- package/dist/internal/text.js +295 -345
- package/dist/internal/text.js.map +1 -1
- package/dist/internal/tokens.d.ts +25 -30
- package/dist/internal/tokens.d.ts.map +1 -1
- package/dist/internal/tokens.js +369 -363
- package/dist/internal/tokens.js.map +1 -1
- package/package.json +42 -28
- package/src/Ascii.ts +278 -187
- package/src/Binary.ts +150 -44
- package/src/Bits.ts +6 -3
- package/src/Compiler.ts +98 -0
- package/src/Expression.ts +10 -5
- package/src/Input.ts +106 -28
- package/src/Nom.ts +4 -3
- package/src/ParseError.ts +48 -51
- package/src/Parser.ts +1163 -795
- package/src/ParserStream.ts +104 -80
- package/src/Syntax.ts +900 -0
- package/src/Text.ts +272 -187
- package/src/Token.ts +180 -87
- package/src/index.ts +2 -0
- package/src/internal/compiler/closure.ts +121 -88
- package/src/internal/compiler/entries.ts +21 -8
- package/src/internal/compiler/first.ts +17 -15
- package/src/internal/compiler/jit.ts +360 -157
- package/src/internal/compiler/registry.ts +12 -33
- package/src/internal/compiler/sets.ts +17 -11
- package/src/internal/entries.ts +4 -2
- package/src/internal/node.ts +51 -37
- package/src/internal/numbers.ts +22 -20
- package/src/internal/resume.ts +8 -4
- package/src/internal/run.ts +41 -0
- package/src/internal/stack.ts +36 -0
- package/src/internal/syntax.ts +421 -0
- package/src/internal/text.ts +32 -25
- package/src/internal/tokens.ts +96 -51
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
package/dist/Text.js
CHANGED
|
@@ -1,529 +1,567 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as Predicate from "effect/Predicate";
|
|
2
2
|
import { Fail } from "./Input.js";
|
|
3
|
-
import
|
|
3
|
+
import * as P from "./Parser.js";
|
|
4
|
+
import { floatText } from "./internal/numbers.js";
|
|
4
5
|
import { codePointPredicate, compile, indexOf, matchLiteral } from "./internal/tokens.js";
|
|
5
|
-
import { floatText as markFloatText } from "./internal/numbers.js";
|
|
6
6
|
import * as internal from "./internal/text.js";
|
|
7
|
-
import
|
|
8
|
-
|
|
7
|
+
import { escapedImpl, overflow, takeEscapedImpl, toFloat as toFloat$1 } from "./Ascii.js";
|
|
8
|
+
import * as Encodings from "./Encoding.js";
|
|
9
|
+
//#region src/Text.ts
|
|
10
|
+
/**
|
|
11
|
+
* Unicode text parsers, generic over the input's encoding.
|
|
12
|
+
*
|
|
13
|
+
* `Text.make(encoding)` builds one set of parsers ({@link TextParsers}) for
|
|
14
|
+
* an {@link Encoding.Encoding}, and ready-made sets are provided for
|
|
15
|
+
* JavaScript strings and the common byte encodings:
|
|
16
|
+
*
|
|
17
|
+
* | Parsers | Input | Offsets |
|
|
18
|
+
* |---|---|---|
|
|
19
|
+
* | `Text.string` | `string` | UTF-16 code units |
|
|
20
|
+
* | `Text.utf8` | `Uint8Array` of UTF-8 | bytes |
|
|
21
|
+
* | `Text.utf16le`, `Text.utf16be` | `Uint8Array` of UTF-16 | bytes |
|
|
22
|
+
* | `Text.latin1` | `Uint8Array` of ISO-8859-1 | bytes |
|
|
23
|
+
*
|
|
24
|
+
* Every set has the same members, and every parser returns `string`s, so a
|
|
25
|
+
* grammar written against `TextParsers<I>` parses all of them:
|
|
26
|
+
*
|
|
27
|
+
* ```ts
|
|
28
|
+
* import { Parser, Text } from "@thomasfosterau/effect-parse"
|
|
29
|
+
*
|
|
30
|
+
* const greeting = <I extends string | Uint8Array>(T: Text.TextParsers<I>) =>
|
|
31
|
+
* Parser.preceded(T.literal("¡hola "), T.identifier)
|
|
32
|
+
*
|
|
33
|
+
* Parser.parse(greeting(Text.string), "¡hola mundo") // "mundo"
|
|
34
|
+
* Parser.parse(greeting(Text.utf8), new TextEncoder().encode("¡hola Zoë")) // "Zoë"
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* Tokens are Unicode code points, and character classes follow Unicode
|
|
38
|
+
* properties: `alpha1` matches `"Ωμέγα"`, `space1` matches a no-break space.
|
|
39
|
+
* Use the `Ascii` module for the ASCII-only classes.
|
|
40
|
+
*
|
|
41
|
+
* Decoding is strict. Malformed input (invalid UTF-8, unpaired surrogates)
|
|
42
|
+
* never matches, and error messages point at it. On partial input, a
|
|
43
|
+
* character split across chunks reports `Incomplete`, so byte streams can be
|
|
44
|
+
* parsed as text without decoding them first.
|
|
45
|
+
*
|
|
46
|
+
* @since 0.1.0
|
|
47
|
+
*/
|
|
48
|
+
const toCodePoint = (c) => Predicate.isNumber(c) ? c : c.codePointAt(0) ?? -1;
|
|
9
49
|
const makePredicate = (name, re) => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
else
|
|
24
|
-
return re.test(String.fromCodePoint(x));
|
|
25
|
-
let v = table[x];
|
|
26
|
-
if (v === 0)
|
|
27
|
-
table[x] = v = re.test(String.fromCharCode(x)) ? 2 : 1;
|
|
28
|
-
return v === 2;
|
|
29
|
-
});
|
|
50
|
+
let ascii;
|
|
51
|
+
let bmp;
|
|
52
|
+
return codePointPredicate(name, (c) => {
|
|
53
|
+
const x = toCodePoint(c);
|
|
54
|
+
if (x < 0) return false;
|
|
55
|
+
let table;
|
|
56
|
+
if (x < 128) table = ascii ??= /* @__PURE__ */ new Uint8Array(128);
|
|
57
|
+
else if (x < 65536) table = bmp ??= /* @__PURE__ */ new Uint8Array(65536);
|
|
58
|
+
else return re.test(String.fromCodePoint(x));
|
|
59
|
+
let v = table[x];
|
|
60
|
+
if (v === 0) table[x] = v = re.test(String.fromCharCode(x)) ? 2 : 1;
|
|
61
|
+
return v === 2;
|
|
62
|
+
});
|
|
30
63
|
};
|
|
31
64
|
/**
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
65
|
+
* A predicate testing a Unicode property, using the syntax of regular
|
|
66
|
+
* expression property escapes (`\p{...}`): a general category (`"Lu"`,
|
|
67
|
+
* `"Letter"`), a binary property (`"Emoji"`, `"Dash"`) or a script
|
|
68
|
+
* (`"Script=Greek"`).
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```ts
|
|
72
|
+
* import { Text } from "@thomasfosterau/effect-parse"
|
|
73
|
+
*
|
|
74
|
+
* const greek = Text.string.takeWhile(Text.property("Script=Greek"), { min: 1 })
|
|
75
|
+
* ```
|
|
76
|
+
*
|
|
77
|
+
* @since 0.1.0
|
|
78
|
+
* @category predicates
|
|
79
|
+
*/
|
|
80
|
+
const property = (name) => makePredicate(name, new RegExp(`^\\p{${name}}$`, "u"));
|
|
48
81
|
/**
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
82
|
+
* Letters and other alphabetic characters (the Unicode `Alphabetic`
|
|
83
|
+
* property, Rust's `char::is_alphabetic`).
|
|
84
|
+
*
|
|
85
|
+
* @since 0.1.0
|
|
86
|
+
* @category predicates
|
|
87
|
+
*/
|
|
88
|
+
const isAlphabetic = /*#__PURE__*/ makePredicate("isAlphabetic", /^\p{Alphabetic}$/u);
|
|
56
89
|
/**
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
90
|
+
* Letters (general category `L`).
|
|
91
|
+
*
|
|
92
|
+
* @since 0.1.0
|
|
93
|
+
* @category predicates
|
|
94
|
+
*/
|
|
95
|
+
const isLetter = /*#__PURE__*/ makePredicate("isLetter", /^\p{L}$/u);
|
|
63
96
|
/**
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
97
|
+
* Uppercase characters (the Unicode `Uppercase` property).
|
|
98
|
+
*
|
|
99
|
+
* @since 0.1.0
|
|
100
|
+
* @category predicates
|
|
101
|
+
*/
|
|
102
|
+
const isUppercase = /*#__PURE__*/ makePredicate("isUppercase", /^\p{Uppercase}$/u);
|
|
70
103
|
/**
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
104
|
+
* Lowercase characters (the Unicode `Lowercase` property).
|
|
105
|
+
*
|
|
106
|
+
* @since 0.1.0
|
|
107
|
+
* @category predicates
|
|
108
|
+
*/
|
|
109
|
+
const isLowercase = /*#__PURE__*/ makePredicate("isLowercase", /^\p{Lowercase}$/u);
|
|
77
110
|
/**
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
111
|
+
* Decimal digits of any script (general category `Nd`): `0`–`9`, `٠`–`٩`,
|
|
112
|
+
* `०`–`९`, ...
|
|
113
|
+
*
|
|
114
|
+
* @since 0.1.0
|
|
115
|
+
* @category predicates
|
|
116
|
+
*/
|
|
117
|
+
const isDecimalDigit = /*#__PURE__*/ makePredicate("isDecimalDigit", /^\p{Nd}$/u);
|
|
85
118
|
/**
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
119
|
+
* Numeric characters (general category `N`), including `½` and `Ⅻ` (Rust's
|
|
120
|
+
* `char::is_numeric`).
|
|
121
|
+
*
|
|
122
|
+
* @since 0.1.0
|
|
123
|
+
* @category predicates
|
|
124
|
+
*/
|
|
125
|
+
const isNumeric = /*#__PURE__*/ makePredicate("isNumeric", /^\p{N}$/u);
|
|
93
126
|
/**
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
127
|
+
* Alphabetic or numeric characters (Rust's `char::is_alphanumeric`).
|
|
128
|
+
*
|
|
129
|
+
* @since 0.1.0
|
|
130
|
+
* @category predicates
|
|
131
|
+
*/
|
|
132
|
+
const isAlphanumeric = /*#__PURE__*/ makePredicate("isAlphanumeric", /^[\p{Alphabetic}\p{N}]$/u);
|
|
100
133
|
/**
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
134
|
+
* Whitespace, including line breaks (the Unicode `White_Space` property,
|
|
135
|
+
* Rust's `char::is_whitespace`).
|
|
136
|
+
*
|
|
137
|
+
* @since 0.1.0
|
|
138
|
+
* @category predicates
|
|
139
|
+
*/
|
|
140
|
+
const isWhitespace = /*#__PURE__*/ makePredicate("isWhitespace", /^\p{White_Space}$/u);
|
|
108
141
|
/**
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
142
|
+
* Whitespace that does not break lines: `White_Space` except `\n`, `\v`,
|
|
143
|
+
* `\f`, `\r`, U+0085, U+2028 and U+2029. Includes tabs and no-break spaces.
|
|
144
|
+
*
|
|
145
|
+
* @since 0.1.0
|
|
146
|
+
* @category predicates
|
|
147
|
+
*/
|
|
148
|
+
const isSpace = /*#__PURE__*/ makePredicate("isSpace", /^(?![\n\v\f\r\u0085\u2028\u2029])\p{White_Space}$/u);
|
|
116
149
|
/**
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
150
|
+
* Characters that can start an identifier (the Unicode `ID_Start` property,
|
|
151
|
+
* see UAX #31).
|
|
152
|
+
*
|
|
153
|
+
* @since 0.1.0
|
|
154
|
+
* @category predicates
|
|
155
|
+
*/
|
|
156
|
+
const isIdStart = /*#__PURE__*/ makePredicate("isIdStart", /^\p{ID_Start}$/u);
|
|
124
157
|
/**
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
158
|
+
* Characters that can continue an identifier (the Unicode `ID_Continue`
|
|
159
|
+
* property, see UAX #31).
|
|
160
|
+
*
|
|
161
|
+
* @since 0.1.0
|
|
162
|
+
* @category predicates
|
|
163
|
+
*/
|
|
164
|
+
const isIdContinue = /*#__PURE__*/ makePredicate("isIdContinue", /^\p{ID_Continue}$/u);
|
|
132
165
|
/**
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
166
|
+
* Punctuation (general category `P`).
|
|
167
|
+
*
|
|
168
|
+
* @since 0.1.0
|
|
169
|
+
* @category predicates
|
|
170
|
+
*/
|
|
171
|
+
const isPunctuation = /*#__PURE__*/ makePredicate("isPunctuation", /^\p{P}$/u);
|
|
139
172
|
/**
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
173
|
+
* Control characters (general category `Cc`).
|
|
174
|
+
*
|
|
175
|
+
* @since 0.1.0
|
|
176
|
+
* @category predicates
|
|
177
|
+
*/
|
|
178
|
+
const isControl = /*#__PURE__*/ makePredicate("isControl", /^\p{Cc}$/u);
|
|
146
179
|
const normalize = (r) => {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
return [r, r];
|
|
151
|
-
return [r.min ?? 0, r.max ?? Infinity];
|
|
180
|
+
if (r === void 0) return [0, Infinity];
|
|
181
|
+
if (Predicate.isNumber(r)) return [r, r];
|
|
182
|
+
return [r.min ?? 0, r.max ?? Infinity];
|
|
152
183
|
};
|
|
153
|
-
const isAsciiDigit = codePointPredicate("isAsciiDigit", (c) => c >= 48 && c <= 57, [[48, 57]]);
|
|
154
|
-
const isAsciiHexDigit = codePointPredicate("isAsciiHexDigit", (c) =>
|
|
184
|
+
const isAsciiDigit = /*#__PURE__*/ codePointPredicate("isAsciiDigit", (c) => c >= 48 && c <= 57, [[48, 57]]);
|
|
185
|
+
const isAsciiHexDigit = /*#__PURE__*/ codePointPredicate("isAsciiHexDigit", (c) => c >= 48 && c <= 57 || c >= 65 && c <= 70 || c >= 97 && c <= 102, [
|
|
186
|
+
[48, 57],
|
|
187
|
+
[65, 70],
|
|
188
|
+
[97, 102]
|
|
189
|
+
]);
|
|
155
190
|
const isLineBreak = (c) => c === 10 || c === 13;
|
|
156
191
|
const expectedAny = ["any character"];
|
|
157
192
|
const expectedLineEnding = ["line ending"];
|
|
158
193
|
const expectedIdentifier = ["identifier"];
|
|
159
194
|
/**
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
195
|
+
* Builds the text parsers for an encoding.
|
|
196
|
+
*
|
|
197
|
+
* @example
|
|
198
|
+
* ```ts
|
|
199
|
+
* import { Encoding, Parser, Text } from "@thomasfosterau/effect-parse"
|
|
200
|
+
*
|
|
201
|
+
* const T = Text.make(Encoding.latin1)
|
|
202
|
+
* Parser.parse(T.alpha1, new Uint8Array([0x63, 0x61, 0x66, 0xe9])) // "café"
|
|
203
|
+
* ```
|
|
204
|
+
*
|
|
205
|
+
* @since 0.1.0
|
|
206
|
+
* @category constructors
|
|
207
|
+
*/
|
|
208
|
+
const make = (encoding) => {
|
|
209
|
+
const enc = encoding;
|
|
210
|
+
const fast = internal.fastLimit(enc);
|
|
211
|
+
const backtrack = (state, kind, expected, offset = state.pos) => state.backtrack(kind, expected, offset);
|
|
212
|
+
/** The text `[start, end)` after checking it is well formed, or `Fail`. */
|
|
213
|
+
const textOf = (state, start, end, kind, expected) => {
|
|
214
|
+
const count = internal.validate(enc, state, start, end);
|
|
215
|
+
if (count < 0) return backtrack(state, kind, expected, -1 - count);
|
|
216
|
+
return enc.text(state.input, start, end);
|
|
217
|
+
};
|
|
218
|
+
const takeWhileText = (test, r, negate, name, expected, kind, hint, set = test) => {
|
|
219
|
+
const [min, max] = normalize(r);
|
|
220
|
+
return P.described((state) => {
|
|
221
|
+
if (state.inputKind === 1) state.encoding = enc;
|
|
222
|
+
const start = state.pos;
|
|
223
|
+
internal.scan(enc, state, test, negate, max, state.pos, fast);
|
|
224
|
+
const offset = internal.scanOffset;
|
|
225
|
+
const count = internal.scanCount;
|
|
226
|
+
const stop = internal.scanStop;
|
|
227
|
+
if (state.partial && (stop === internal.End || stop === internal.Truncated)) return state.incomplete(1, expected);
|
|
228
|
+
if (count < min) return backtrack(state, kind, expected, offset);
|
|
229
|
+
if (hint && count < max) state.setHint(offset, expected);
|
|
230
|
+
state.pos = offset;
|
|
231
|
+
return enc.text(state.input, start, offset);
|
|
232
|
+
}, name, {
|
|
233
|
+
_tag: "TakeWhile",
|
|
234
|
+
set,
|
|
235
|
+
negate,
|
|
236
|
+
min,
|
|
237
|
+
max,
|
|
238
|
+
encoding: enc
|
|
239
|
+
});
|
|
240
|
+
};
|
|
241
|
+
const any = P.described((state) => {
|
|
242
|
+
if (state.inputKind === 1) state.encoding = enc;
|
|
243
|
+
const cp = internal.next(enc, state);
|
|
244
|
+
if (cp < 0) return internal.failAt(state, cp, "Token", expectedAny);
|
|
245
|
+
state.pos += internal.width;
|
|
246
|
+
return internal.charOf(cp);
|
|
247
|
+
}, "any", {
|
|
248
|
+
_tag: "Any",
|
|
249
|
+
encoding: enc
|
|
250
|
+
});
|
|
251
|
+
const literal = (lit) => {
|
|
252
|
+
const encoded = enc.encode(lit);
|
|
253
|
+
const len = encoded.length;
|
|
254
|
+
const expected = [JSON.stringify(lit)];
|
|
255
|
+
const node = {
|
|
256
|
+
_tag: "Literal",
|
|
257
|
+
literal: lit,
|
|
258
|
+
caseless: false,
|
|
259
|
+
encoding: enc
|
|
260
|
+
};
|
|
261
|
+
if (len === 1) {
|
|
262
|
+
const unit = Predicate.isString(encoded) ? encoded.charCodeAt(0) : encoded[0];
|
|
263
|
+
return P.described((state) => {
|
|
264
|
+
const pos = state.pos;
|
|
265
|
+
if (state.inputKind === 1) state.encoding = enc;
|
|
266
|
+
if (pos >= state.end) return state.eoi("Literal", expected, 1);
|
|
267
|
+
const input = state.input;
|
|
268
|
+
if ((state.inputKind === 0 ? input.charCodeAt(pos) : input[pos]) !== unit) return backtrack(state, "Literal", expected);
|
|
269
|
+
state.pos = pos + 1;
|
|
270
|
+
return lit;
|
|
271
|
+
}, expected[0], node);
|
|
272
|
+
}
|
|
273
|
+
return P.described((state) => {
|
|
274
|
+
if (state.inputKind === 1) state.encoding = enc;
|
|
275
|
+
const r = matchLiteral(state, encoded, false);
|
|
276
|
+
if (r === -1) return backtrack(state, "Literal", expected);
|
|
277
|
+
if (r === -2) {
|
|
278
|
+
if (state.partial) return state.incomplete(len - (state.end - state.pos), expected);
|
|
279
|
+
return backtrack(state, "Literal", expected);
|
|
280
|
+
}
|
|
281
|
+
state.pos += len;
|
|
282
|
+
return lit;
|
|
283
|
+
}, expected[0], node);
|
|
284
|
+
};
|
|
285
|
+
const caseless = (lit) => {
|
|
286
|
+
const folded = Array.from(lit, (c) => internal.fold(internal.firstCodePoint(c)));
|
|
287
|
+
const expected = [`${JSON.stringify(lit)} (case insensitive)`];
|
|
288
|
+
return P.described((state) => {
|
|
289
|
+
if (state.inputKind === 1) state.encoding = enc;
|
|
290
|
+
const start = state.pos;
|
|
291
|
+
let pos = start;
|
|
292
|
+
for (let i = 0; i < folded.length; i++) {
|
|
293
|
+
const cp = internal.next(enc, state, pos);
|
|
294
|
+
if (cp === internal.End || cp === internal.Truncated) return state.partial ? state.incomplete(1, expected) : backtrack(state, "Literal", expected);
|
|
295
|
+
if (cp < 0 || internal.fold(cp) !== folded[i]) {
|
|
296
|
+
state.syntax?.read(pos + Math.max(internal.width, 1));
|
|
297
|
+
return backtrack(state, "Literal", expected);
|
|
298
|
+
}
|
|
299
|
+
pos += internal.width;
|
|
300
|
+
}
|
|
301
|
+
state.pos = pos;
|
|
302
|
+
return enc.text(state.input, start, pos);
|
|
303
|
+
}, expected[0], {
|
|
304
|
+
_tag: "Literal",
|
|
305
|
+
literal: lit,
|
|
306
|
+
caseless: true,
|
|
307
|
+
encoding: enc
|
|
308
|
+
});
|
|
309
|
+
};
|
|
310
|
+
const oneOfImpl = (set, negate) => {
|
|
311
|
+
const m = compile(set, "string");
|
|
312
|
+
const test = m.code;
|
|
313
|
+
const expected = [negate ? `anything but ${m.description}` : m.description];
|
|
314
|
+
const kind = negate ? "NoneOf" : "OneOf";
|
|
315
|
+
return P.described((state) => {
|
|
316
|
+
if (state.inputKind === 1) state.encoding = enc;
|
|
317
|
+
const cp = internal.next(enc, state);
|
|
318
|
+
if (cp < 0) return internal.failAt(state, cp, kind, expected);
|
|
319
|
+
const w = internal.width;
|
|
320
|
+
if (test(cp) === negate) return state.backtrack(kind, expected);
|
|
321
|
+
state.pos += w;
|
|
322
|
+
return internal.charOf(cp);
|
|
323
|
+
}, expected[0], {
|
|
324
|
+
_tag: "OneOf",
|
|
325
|
+
set,
|
|
326
|
+
negate,
|
|
327
|
+
encoding: enc
|
|
328
|
+
});
|
|
329
|
+
};
|
|
330
|
+
const take = (count) => {
|
|
331
|
+
const expected = [count === 1 ? "1 character" : `${count} characters`];
|
|
332
|
+
return P.described((state) => {
|
|
333
|
+
if (state.inputKind === 1) state.encoding = enc;
|
|
334
|
+
const start = state.pos;
|
|
335
|
+
let pos = start;
|
|
336
|
+
for (let got = 0; got < count; got++) {
|
|
337
|
+
const cp = internal.next(enc, state, pos);
|
|
338
|
+
if (cp === internal.End) return state.eoi("Take", expected, count - got);
|
|
339
|
+
if (cp < 0) return internal.failAt(state, cp, "Take", expected, pos);
|
|
340
|
+
pos += internal.width;
|
|
341
|
+
}
|
|
342
|
+
state.pos = pos;
|
|
343
|
+
return enc.text(state.input, start, pos);
|
|
344
|
+
}, "take", {
|
|
345
|
+
_tag: "Take",
|
|
346
|
+
count,
|
|
347
|
+
encoding: enc
|
|
348
|
+
});
|
|
349
|
+
};
|
|
350
|
+
const takeUntil = (lit, r) => {
|
|
351
|
+
const [min, max] = normalize(r);
|
|
352
|
+
const needle = enc.encode(lit);
|
|
353
|
+
const unit = enc.unit;
|
|
354
|
+
const expected = [JSON.stringify(lit)];
|
|
355
|
+
return P.described((state) => {
|
|
356
|
+
if (state.inputKind === 1) state.encoding = enc;
|
|
357
|
+
const start = state.pos;
|
|
358
|
+
let idx = indexOf(state, needle, start);
|
|
359
|
+
while (unit > 1 && idx >= 0 && (idx - start) % unit !== 0) idx = indexOf(state, needle, idx + 1);
|
|
360
|
+
if (idx < 0) {
|
|
361
|
+
if (state.partial) return state.incomplete(0, expected);
|
|
362
|
+
return backtrack(state, "TakeUntil", expected, state.end);
|
|
363
|
+
}
|
|
364
|
+
state.syntax?.read(idx + needle.length);
|
|
365
|
+
const count = internal.validate(enc, state, start, idx);
|
|
366
|
+
if (count < 0) return backtrack(state, "TakeUntil", expected, -1 - count);
|
|
367
|
+
if (count < min) return backtrack(state, "TakeUntil", expected, idx);
|
|
368
|
+
if (count > max) return backtrack(state, "TakeUntil", expected);
|
|
369
|
+
state.pos = idx;
|
|
370
|
+
return enc.text(state.input, start, idx);
|
|
371
|
+
}, "takeUntil", {
|
|
372
|
+
_tag: "TakeUntil",
|
|
373
|
+
literal: lit,
|
|
374
|
+
min,
|
|
375
|
+
max,
|
|
376
|
+
encoding: enc
|
|
377
|
+
});
|
|
378
|
+
};
|
|
379
|
+
const always = () => true;
|
|
380
|
+
const rest = P.described((state) => {
|
|
381
|
+
if (state.inputKind === 1) state.encoding = enc;
|
|
382
|
+
const start = state.pos;
|
|
383
|
+
internal.scan(enc, state, always, false, Infinity, state.pos, fast);
|
|
384
|
+
const offset = internal.scanOffset;
|
|
385
|
+
if (internal.scanStop === internal.Truncated) return state.incomplete(1, expectedAny);
|
|
386
|
+
if (internal.scanStop === internal.Invalid) return backtrack(state, "Token", expectedAny, offset);
|
|
387
|
+
state.pos = offset;
|
|
388
|
+
return enc.text(state.input, start, offset);
|
|
389
|
+
}, "rest", {
|
|
390
|
+
_tag: "Rest",
|
|
391
|
+
encoding: enc
|
|
392
|
+
});
|
|
393
|
+
const taken = (self) => {
|
|
394
|
+
const step = self.step;
|
|
395
|
+
return P.described((state) => {
|
|
396
|
+
if (state.inputKind === 1) state.encoding = enc;
|
|
397
|
+
const start = state.pos;
|
|
398
|
+
if (step(state) === Fail) return Fail;
|
|
399
|
+
return textOf(state, start, state.pos, "Slice", expectedAny);
|
|
400
|
+
}, self.name, {
|
|
401
|
+
_tag: "Taken",
|
|
402
|
+
self,
|
|
403
|
+
encoding: enc
|
|
404
|
+
});
|
|
405
|
+
};
|
|
406
|
+
const cls = (test, min, description, kind, hint = true) => takeWhileText(test, { min }, false, `${kind.toLowerCase()}${min}`, [description], kind, hint);
|
|
407
|
+
const identifierStart = (cp) => cp === 95 || isIdStart(cp);
|
|
408
|
+
const identifier = P.described((state) => {
|
|
409
|
+
if (state.inputKind === 1) state.encoding = enc;
|
|
410
|
+
const start = state.pos;
|
|
411
|
+
const cp = internal.next(enc, state);
|
|
412
|
+
if (cp < 0) return internal.failAt(state, cp, "TakeWhile", expectedIdentifier);
|
|
413
|
+
if (!identifierStart(cp)) return state.backtrack("TakeWhile", expectedIdentifier);
|
|
414
|
+
internal.scan(enc, state, isIdContinue, false, Infinity, start + internal.width, fast);
|
|
415
|
+
const stop = internal.scanStop;
|
|
416
|
+
if (state.partial && (stop === internal.End || stop === internal.Truncated)) return state.incomplete(1, expectedIdentifier);
|
|
417
|
+
state.pos = internal.scanOffset;
|
|
418
|
+
return enc.text(state.input, start, state.pos);
|
|
419
|
+
}, "identifier", {
|
|
420
|
+
_tag: "Identifier",
|
|
421
|
+
encoding: enc
|
|
422
|
+
});
|
|
423
|
+
const bom = P.described((state) => {
|
|
424
|
+
if (state.inputKind === 1) state.encoding = enc;
|
|
425
|
+
const cp = internal.next(enc, state);
|
|
426
|
+
if (cp === 65279) {
|
|
427
|
+
state.pos += internal.width;
|
|
428
|
+
return true;
|
|
429
|
+
}
|
|
430
|
+
if (cp === internal.Truncated || cp === internal.End && state.partial) return state.incomplete(1, ["byte order mark"]);
|
|
431
|
+
return false;
|
|
432
|
+
}, "bom", {
|
|
433
|
+
_tag: "Bom",
|
|
434
|
+
encoding: enc
|
|
435
|
+
});
|
|
436
|
+
const newline = literal("\n");
|
|
437
|
+
const crlf = literal("\r\n");
|
|
438
|
+
const tillLineEnding = P.described((state) => {
|
|
439
|
+
if (state.inputKind === 1) state.encoding = enc;
|
|
440
|
+
const start = state.pos;
|
|
441
|
+
internal.scan(enc, state, isLineBreak, true, Infinity, state.pos, fast);
|
|
442
|
+
const offset = internal.scanOffset;
|
|
443
|
+
const stop = internal.scanStop;
|
|
444
|
+
if (stop === internal.Truncated || stop === internal.End && state.partial) return state.incomplete(1, expectedLineEnding);
|
|
445
|
+
if (stop === internal.Invalid) return backtrack(state, "LineEnding", expectedLineEnding, offset);
|
|
446
|
+
if (stop === 0 && internal.next(enc, state, offset) === 13) {
|
|
447
|
+
const cr = internal.width;
|
|
448
|
+
state.syntax?.read(offset + 2 * cr);
|
|
449
|
+
const after = internal.next(enc, state, offset + cr);
|
|
450
|
+
if (after === internal.End && state.partial) return state.incomplete(1, expectedLineEnding);
|
|
451
|
+
if (after !== 10) return backtrack(state, "LineEnding", expectedLineEnding, offset);
|
|
452
|
+
}
|
|
453
|
+
state.pos = offset;
|
|
454
|
+
return enc.text(state.input, start, offset);
|
|
455
|
+
}, "tillLineEnding", {
|
|
456
|
+
_tag: "TillLineEnding",
|
|
457
|
+
encoding: enc
|
|
458
|
+
});
|
|
459
|
+
const asciiDigits = takeWhileText(isAsciiDigit, { min: 1 }, false, "digit1", ["digit"], "Digit", true);
|
|
460
|
+
const hexDigits = takeWhileText(isAsciiHexDigit, { min: 1 }, false, "hexDigit1", ["hexadecimal digit"], "HexDigit", true);
|
|
461
|
+
const sign = P.opt(oneOfImpl("+-", false));
|
|
462
|
+
const signed = taken(P.seq(sign, asciiDigits));
|
|
463
|
+
const exponent = P.opt(P.seq(oneOfImpl("eE", false), sign, asciiDigits));
|
|
464
|
+
const unsignedFloat = P.alt(P.seq(caseless("inf"), P.opt(caseless("inity"))), P.seq(literal("."), asciiDigits, exponent), P.seq(asciiDigits, P.opt(P.seq(literal("."), P.opt(asciiDigits))), exponent));
|
|
465
|
+
const floatText$1 = floatText(taken(P.alt(caseless("nan"), P.seq(sign, unsignedFloat))).pipe(P.expected("number")));
|
|
466
|
+
const matchControl = (control) => {
|
|
467
|
+
const ctrl = control.codePointAt(0);
|
|
468
|
+
return (state) => {
|
|
469
|
+
if (internal.next(enc, state) !== ctrl) return false;
|
|
470
|
+
state.pos += internal.width;
|
|
471
|
+
return true;
|
|
472
|
+
};
|
|
473
|
+
};
|
|
474
|
+
return {
|
|
475
|
+
encoding,
|
|
476
|
+
any,
|
|
477
|
+
literal,
|
|
478
|
+
caseless,
|
|
479
|
+
oneOf: (set) => oneOfImpl(set, false),
|
|
480
|
+
noneOf: (set) => oneOfImpl(set, true),
|
|
481
|
+
bom,
|
|
482
|
+
take,
|
|
483
|
+
takeWhile: (set, r) => {
|
|
484
|
+
const m = compile(set, "string");
|
|
485
|
+
return takeWhileText(m.code, r, false, "takeWhile", [m.description], "TakeWhile", false, set);
|
|
486
|
+
},
|
|
487
|
+
takeTill: (set, r) => {
|
|
488
|
+
const m = compile(set, "string");
|
|
489
|
+
return takeWhileText(m.code, r, true, "takeTill", [`anything but ${m.description}`], "TakeWhile", false, set);
|
|
490
|
+
},
|
|
491
|
+
takeUntil,
|
|
492
|
+
rest,
|
|
493
|
+
taken,
|
|
494
|
+
alpha0: cls(isAlphabetic, 0, "letter", "Alpha"),
|
|
495
|
+
alpha1: cls(isAlphabetic, 1, "letter", "Alpha"),
|
|
496
|
+
digit0: cls(isDecimalDigit, 0, "digit", "Digit"),
|
|
497
|
+
digit1: cls(isDecimalDigit, 1, "digit", "Digit"),
|
|
498
|
+
alphanumeric0: cls(isAlphanumeric, 0, "letter or digit", "AlphaNumeric"),
|
|
499
|
+
alphanumeric1: cls(isAlphanumeric, 1, "letter or digit", "AlphaNumeric"),
|
|
500
|
+
space0: cls(isSpace, 0, "space", "Space", false),
|
|
501
|
+
space1: cls(isSpace, 1, "space", "Space", false),
|
|
502
|
+
multispace0: cls(isWhitespace, 0, "whitespace", "MultiSpace", false),
|
|
503
|
+
multispace1: cls(isWhitespace, 1, "whitespace", "MultiSpace", false),
|
|
504
|
+
identifier,
|
|
505
|
+
newline,
|
|
506
|
+
crlf,
|
|
507
|
+
tab: literal(" "),
|
|
508
|
+
lineEnding: P.alt(newline, crlf).pipe(P.expected("line ending")),
|
|
509
|
+
tillLineEnding,
|
|
510
|
+
decUint: asciiDigits.pipe(P.tryMap((s) => overflow(Number(s))), P.named("decUint")),
|
|
511
|
+
decInt: signed.pipe(P.tryMap((s) => overflow(Number(s))), P.named("decInt")),
|
|
512
|
+
decBigUint: asciiDigits.pipe(P.map((s) => BigInt(s))),
|
|
513
|
+
decBigInt: signed.pipe(P.map((s) => BigInt(s.startsWith("+") ? s.slice(1) : s))),
|
|
514
|
+
hexUint: hexDigits.pipe(P.tryMap((s) => overflow(parseInt(s, 16))), P.named("hexUint")),
|
|
515
|
+
float: floatText$1.pipe(P.map(toFloat$1), P.named("float")),
|
|
516
|
+
takeEscaped: (normal, control, escapable) => takeEscapedImpl(normal, matchControl(control), escapable, (state, start) => enc.text(state.input, start, state.pos), internal.firstCodePoint(control), enc),
|
|
517
|
+
escaped: (normal, control, escape) => escapedImpl(normal, matchControl(control), escape, internal.firstCodePoint(control), enc)
|
|
518
|
+
};
|
|
484
519
|
};
|
|
485
520
|
/**
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
521
|
+
* Text parsers for JavaScript strings.
|
|
522
|
+
*
|
|
523
|
+
* @since 0.1.0
|
|
524
|
+
* @category instances
|
|
525
|
+
*/
|
|
526
|
+
const string = /*#__PURE__*/ make(Encodings.string);
|
|
492
527
|
/**
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
528
|
+
* Text parsers for UTF-8 encoded bytes.
|
|
529
|
+
*
|
|
530
|
+
* @example
|
|
531
|
+
* ```ts
|
|
532
|
+
* import { Parser, Text } from "@thomasfosterau/effect-parse"
|
|
533
|
+
*
|
|
534
|
+
* const bytes = new TextEncoder().encode("naïve café")
|
|
535
|
+
* Parser.parse(Parser.separatedPair(Text.utf8.alpha1, Text.utf8.space1, Text.utf8.alpha1), bytes)
|
|
536
|
+
* // Result.succeed(["naïve", "café"])
|
|
537
|
+
* ```
|
|
538
|
+
*
|
|
539
|
+
* @since 0.1.0
|
|
540
|
+
* @category instances
|
|
541
|
+
*/
|
|
542
|
+
const utf8 = /*#__PURE__*/ make(Encodings.utf8);
|
|
508
543
|
/**
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
544
|
+
* Text parsers for UTF-16 little endian bytes.
|
|
545
|
+
*
|
|
546
|
+
* @since 0.1.0
|
|
547
|
+
* @category instances
|
|
548
|
+
*/
|
|
549
|
+
const utf16le = /*#__PURE__*/ make(Encodings.utf16le);
|
|
515
550
|
/**
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
551
|
+
* Text parsers for UTF-16 big endian bytes.
|
|
552
|
+
*
|
|
553
|
+
* @since 0.1.0
|
|
554
|
+
* @category instances
|
|
555
|
+
*/
|
|
556
|
+
const utf16be = /*#__PURE__*/ make(Encodings.utf16be);
|
|
522
557
|
/**
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
558
|
+
* Text parsers for ISO-8859-1 (Latin-1) bytes.
|
|
559
|
+
*
|
|
560
|
+
* @since 0.1.0
|
|
561
|
+
* @category instances
|
|
562
|
+
*/
|
|
563
|
+
const latin1 = /*#__PURE__*/ make(Encodings.latin1);
|
|
564
|
+
//#endregion
|
|
565
|
+
export { isAlphabetic, isAlphanumeric, isControl, isDecimalDigit, isIdContinue, isIdStart, isLetter, isLowercase, isNumeric, isPunctuation, isSpace, isUppercase, isWhitespace, latin1, make, property, string, utf16be, utf16le, utf8 };
|
|
566
|
+
|
|
529
567
|
//# sourceMappingURL=Text.js.map
|