@futpib/parser 1.0.3 → 1.0.4
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/bash.d.ts +84 -0
- package/build/bash.js +1 -0
- package/build/bashParser.d.ts +6 -0
- package/build/bashParser.js +294 -0
- package/build/bashParser.test.d.ts +1 -0
- package/build/bashParser.test.js +181 -0
- package/build/index.d.ts +24 -2
- package/build/index.js +22 -1
- package/build/regexpParser.d.ts +2 -0
- package/build/regexpParser.js +71 -0
- package/build/regexpParser.test.d.ts +1 -0
- package/build/regexpParser.test.js +83 -0
- package/build/regularExpression.d.ts +63 -0
- package/build/regularExpression.js +1 -0
- package/build/regularExpressionParser.d.ts +3 -0
- package/build/regularExpressionParser.js +580 -0
- package/build/regularExpressionParser.test.d.ts +1 -0
- package/build/regularExpressionParser.test.js +89 -0
- package/package.json +2 -1
- package/src/bash.ts +120 -0
- package/src/bashParser.test.ts +332 -0
- package/src/bashParser.ts +461 -0
- package/src/index.ts +113 -2
- package/src/regexpParser.test.ts +186 -0
- package/src/regexpParser.ts +94 -0
- package/src/regularExpression.ts +24 -0
- package/src/regularExpressionParser.test.ts +102 -0
- package/src/regularExpressionParser.ts +921 -0
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
import { type Parser, setParserName } from './parser.js';
|
|
2
|
+
import { createUnionParser } from './unionParser.js';
|
|
3
|
+
import { createExactSequenceParser } from './exactSequenceParser.js';
|
|
4
|
+
import { promiseCompose } from './promiseCompose.js';
|
|
5
|
+
import { createTupleParser } from './tupleParser.js';
|
|
6
|
+
import { createDisjunctionParser } from './disjunctionParser.js';
|
|
7
|
+
import { createArrayParser } from './arrayParser.js';
|
|
8
|
+
import { createParserAccessorParser } from './parserAccessorParser.js';
|
|
9
|
+
import { createOptionalParser } from './optionalParser.js';
|
|
10
|
+
import { createRegExpParser } from './regexpParser.js';
|
|
11
|
+
import { createNonEmptyArrayParser } from './nonEmptyArrayParser.js';
|
|
12
|
+
import { createSeparatedNonEmptyArrayParser } from './separatedNonEmptyArrayParser.js';
|
|
13
|
+
import {
|
|
14
|
+
type BashWord,
|
|
15
|
+
type BashWordPart,
|
|
16
|
+
type BashWordPartLiteral,
|
|
17
|
+
type BashWordPartSingleQuoted,
|
|
18
|
+
type BashWordPartDoubleQuoted,
|
|
19
|
+
type BashWordPartVariable,
|
|
20
|
+
type BashWordPartCommandSubstitution,
|
|
21
|
+
type BashWordPartBacktickSubstitution,
|
|
22
|
+
type BashSimpleCommand,
|
|
23
|
+
type BashSubshell,
|
|
24
|
+
type BashBraceGroup,
|
|
25
|
+
type BashCommandUnit,
|
|
26
|
+
type BashPipeline,
|
|
27
|
+
type BashCommandList,
|
|
28
|
+
type BashRedirect,
|
|
29
|
+
type BashAssignment,
|
|
30
|
+
type BashCommand,
|
|
31
|
+
} from './bash.js';
|
|
32
|
+
|
|
33
|
+
// Whitespace (spaces and tabs, not newlines - those are significant)
|
|
34
|
+
const bashInlineWhitespaceParser: Parser<string, string> = promiseCompose(
|
|
35
|
+
createRegExpParser(/[ \t]+/),
|
|
36
|
+
match => match[0],
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
const bashOptionalInlineWhitespaceParser: Parser<string, string> = promiseCompose(
|
|
40
|
+
createRegExpParser(/[ \t]*/),
|
|
41
|
+
match => match[0],
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
// Newline
|
|
45
|
+
const bashNewlineParser: Parser<string, string> = promiseCompose(
|
|
46
|
+
createRegExpParser(/\n/),
|
|
47
|
+
match => match[0],
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
// Word characters (unquoted, no special chars)
|
|
51
|
+
// Note: {} are excluded so brace groups are parsed correctly
|
|
52
|
+
const bashUnquotedWordCharsParser: Parser<string, string> = promiseCompose(
|
|
53
|
+
createRegExpParser(/[^\s\n|&;<>(){}$`"'\\#]+/),
|
|
54
|
+
match => match[0],
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
// Single quoted string: '...'
|
|
58
|
+
const bashSingleQuotedParser: Parser<BashWordPartSingleQuoted, string> = promiseCompose(
|
|
59
|
+
createTupleParser([
|
|
60
|
+
createExactSequenceParser("'"),
|
|
61
|
+
promiseCompose(
|
|
62
|
+
createRegExpParser(/[^']*/),
|
|
63
|
+
match => match[0],
|
|
64
|
+
),
|
|
65
|
+
createExactSequenceParser("'"),
|
|
66
|
+
]),
|
|
67
|
+
([, value]) => ({
|
|
68
|
+
type: 'singleQuoted' as const,
|
|
69
|
+
value,
|
|
70
|
+
}),
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
// Variable name
|
|
74
|
+
const bashVariableNameParser: Parser<string, string> = promiseCompose(
|
|
75
|
+
createRegExpParser(/[a-zA-Z_][a-zA-Z0-9_]*|[0-9]+|[@*#?$!-]/),
|
|
76
|
+
match => match[0],
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
// Simple variable: $var
|
|
80
|
+
const bashSimpleVariableParser: Parser<BashWordPartVariable, string> = promiseCompose(
|
|
81
|
+
createTupleParser([
|
|
82
|
+
createExactSequenceParser('$'),
|
|
83
|
+
bashVariableNameParser,
|
|
84
|
+
]),
|
|
85
|
+
([, name]) => ({
|
|
86
|
+
type: 'variable' as const,
|
|
87
|
+
name,
|
|
88
|
+
}),
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
// Command substitution: $(...)
|
|
92
|
+
const bashCommandSubstitutionParser: Parser<BashWordPartCommandSubstitution, string> = promiseCompose(
|
|
93
|
+
createTupleParser([
|
|
94
|
+
createExactSequenceParser('$('),
|
|
95
|
+
bashOptionalInlineWhitespaceParser,
|
|
96
|
+
createParserAccessorParser(() => bashCommandParser),
|
|
97
|
+
bashOptionalInlineWhitespaceParser,
|
|
98
|
+
createExactSequenceParser(')'),
|
|
99
|
+
]),
|
|
100
|
+
([, , command]) => ({
|
|
101
|
+
type: 'commandSubstitution' as const,
|
|
102
|
+
command,
|
|
103
|
+
}),
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
// Backtick substitution: `...`
|
|
107
|
+
const bashBacktickSubstitutionParser: Parser<BashWordPartBacktickSubstitution, string> = promiseCompose(
|
|
108
|
+
createTupleParser([
|
|
109
|
+
createExactSequenceParser('`'),
|
|
110
|
+
createParserAccessorParser(() => bashCommandParser),
|
|
111
|
+
createExactSequenceParser('`'),
|
|
112
|
+
]),
|
|
113
|
+
([, command]) => ({
|
|
114
|
+
type: 'backtickSubstitution' as const,
|
|
115
|
+
command,
|
|
116
|
+
}),
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
// Double quoted string parts (inside "...")
|
|
120
|
+
const bashDoubleQuotedPartParser: Parser<BashWordPart, string> = createDisjunctionParser([
|
|
121
|
+
bashSimpleVariableParser,
|
|
122
|
+
bashCommandSubstitutionParser,
|
|
123
|
+
bashBacktickSubstitutionParser,
|
|
124
|
+
// Escape sequences in double quotes
|
|
125
|
+
promiseCompose(
|
|
126
|
+
createRegExpParser(/\\[\\$`"!\n]/),
|
|
127
|
+
match => ({
|
|
128
|
+
type: 'literal' as const,
|
|
129
|
+
value: match[0].slice(1),
|
|
130
|
+
}),
|
|
131
|
+
),
|
|
132
|
+
// Literal text (no special chars)
|
|
133
|
+
promiseCompose(
|
|
134
|
+
createRegExpParser(/[^$`"\\]+/),
|
|
135
|
+
match => ({
|
|
136
|
+
type: 'literal' as const,
|
|
137
|
+
value: match[0],
|
|
138
|
+
}),
|
|
139
|
+
),
|
|
140
|
+
]);
|
|
141
|
+
|
|
142
|
+
// Double quoted string: "..."
|
|
143
|
+
const bashDoubleQuotedParser: Parser<BashWordPartDoubleQuoted, string> = promiseCompose(
|
|
144
|
+
createTupleParser([
|
|
145
|
+
createExactSequenceParser('"'),
|
|
146
|
+
createArrayParser(bashDoubleQuotedPartParser),
|
|
147
|
+
createExactSequenceParser('"'),
|
|
148
|
+
]),
|
|
149
|
+
([, parts]) => ({
|
|
150
|
+
type: 'doubleQuoted' as const,
|
|
151
|
+
parts,
|
|
152
|
+
}),
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
// Literal word part (unquoted)
|
|
156
|
+
const bashLiteralWordPartParser: Parser<BashWordPartLiteral, string> = promiseCompose(
|
|
157
|
+
bashUnquotedWordCharsParser,
|
|
158
|
+
value => ({
|
|
159
|
+
type: 'literal' as const,
|
|
160
|
+
value,
|
|
161
|
+
}),
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
// Escape sequence outside quotes
|
|
165
|
+
const bashEscapeParser: Parser<BashWordPartLiteral, string> = promiseCompose(
|
|
166
|
+
createRegExpParser(/\\./),
|
|
167
|
+
match => ({
|
|
168
|
+
type: 'literal' as const,
|
|
169
|
+
value: match[0].slice(1),
|
|
170
|
+
}),
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
// Word part (any part of a word)
|
|
174
|
+
const bashWordPartParser: Parser<BashWordPart, string> = createDisjunctionParser([
|
|
175
|
+
bashSingleQuotedParser,
|
|
176
|
+
bashDoubleQuotedParser,
|
|
177
|
+
bashCommandSubstitutionParser,
|
|
178
|
+
bashBacktickSubstitutionParser,
|
|
179
|
+
bashSimpleVariableParser,
|
|
180
|
+
bashEscapeParser,
|
|
181
|
+
bashLiteralWordPartParser,
|
|
182
|
+
]);
|
|
183
|
+
|
|
184
|
+
// Word (sequence of word parts)
|
|
185
|
+
export const bashWordParser: Parser<BashWord, string> = promiseCompose(
|
|
186
|
+
createNonEmptyArrayParser(bashWordPartParser),
|
|
187
|
+
parts => ({ parts }),
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
setParserName(bashWordParser, 'bashWordParser');
|
|
191
|
+
|
|
192
|
+
// Assignment: NAME=value or NAME=
|
|
193
|
+
const bashAssignmentParser: Parser<BashAssignment, string> = promiseCompose(
|
|
194
|
+
createTupleParser([
|
|
195
|
+
promiseCompose(
|
|
196
|
+
createRegExpParser(/[a-zA-Z_][a-zA-Z0-9_]*=/),
|
|
197
|
+
match => match[0].slice(0, -1),
|
|
198
|
+
),
|
|
199
|
+
createOptionalParser(bashWordParser),
|
|
200
|
+
]),
|
|
201
|
+
([name, value]) => ({
|
|
202
|
+
name,
|
|
203
|
+
value: value ?? undefined,
|
|
204
|
+
}),
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
// Redirect operators
|
|
208
|
+
const bashRedirectOperatorParser: Parser<BashRedirect['operator'], string> = createDisjunctionParser([
|
|
209
|
+
promiseCompose(createExactSequenceParser('>>'), () => '>>' as const),
|
|
210
|
+
promiseCompose(createExactSequenceParser('>&'), () => '>&' as const),
|
|
211
|
+
promiseCompose(createExactSequenceParser('>|'), () => '>|' as const),
|
|
212
|
+
promiseCompose(createExactSequenceParser('>'), () => '>' as const),
|
|
213
|
+
promiseCompose(createExactSequenceParser('<<<'), () => '<<<' as const),
|
|
214
|
+
promiseCompose(createExactSequenceParser('<<'), () => '<<' as const),
|
|
215
|
+
promiseCompose(createExactSequenceParser('<&'), () => '<&' as const),
|
|
216
|
+
promiseCompose(createExactSequenceParser('<'), () => '<' as const),
|
|
217
|
+
]);
|
|
218
|
+
|
|
219
|
+
// Redirect: [n]op word
|
|
220
|
+
const bashRedirectParser: Parser<BashRedirect, string> = promiseCompose(
|
|
221
|
+
createTupleParser([
|
|
222
|
+
createOptionalParser(promiseCompose(
|
|
223
|
+
createRegExpParser(/[0-9]+/),
|
|
224
|
+
match => Number.parseInt(match[0], 10),
|
|
225
|
+
)),
|
|
226
|
+
bashRedirectOperatorParser,
|
|
227
|
+
bashOptionalInlineWhitespaceParser,
|
|
228
|
+
bashWordParser,
|
|
229
|
+
]),
|
|
230
|
+
([fd, operator, , target]) => ({
|
|
231
|
+
fd: fd ?? undefined,
|
|
232
|
+
operator,
|
|
233
|
+
target,
|
|
234
|
+
}),
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
// Word with optional trailing whitespace - for use in arrays
|
|
238
|
+
const bashWordWithWhitespaceParser: Parser<BashWord, string> = promiseCompose(
|
|
239
|
+
createTupleParser([
|
|
240
|
+
bashWordParser,
|
|
241
|
+
bashOptionalInlineWhitespaceParser,
|
|
242
|
+
]),
|
|
243
|
+
([word]) => word,
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
// Redirect with optional trailing whitespace
|
|
247
|
+
const bashRedirectWithWhitespaceParser: Parser<BashRedirect, string> = promiseCompose(
|
|
248
|
+
createTupleParser([
|
|
249
|
+
bashRedirectParser,
|
|
250
|
+
bashOptionalInlineWhitespaceParser,
|
|
251
|
+
]),
|
|
252
|
+
([redirect]) => redirect,
|
|
253
|
+
);
|
|
254
|
+
|
|
255
|
+
// Word or redirect - for interleaved parsing in simple commands
|
|
256
|
+
const bashWordOrRedirectParser: Parser<{ type: 'word'; word: BashWord } | { type: 'redirect'; redirect: BashRedirect }, string> = createDisjunctionParser([
|
|
257
|
+
promiseCompose(bashRedirectWithWhitespaceParser, redirect => ({ type: 'redirect' as const, redirect })),
|
|
258
|
+
promiseCompose(bashWordWithWhitespaceParser, word => ({ type: 'word' as const, word })),
|
|
259
|
+
]);
|
|
260
|
+
|
|
261
|
+
// Simple command: [assignments] [name] [args] [redirects]
|
|
262
|
+
export const bashSimpleCommandParser: Parser<BashSimpleCommand, string> = promiseCompose(
|
|
263
|
+
createTupleParser([
|
|
264
|
+
// Assignments at the start
|
|
265
|
+
createArrayParser(promiseCompose(
|
|
266
|
+
createTupleParser([
|
|
267
|
+
bashAssignmentParser,
|
|
268
|
+
bashOptionalInlineWhitespaceParser,
|
|
269
|
+
]),
|
|
270
|
+
([assignment]) => assignment,
|
|
271
|
+
)),
|
|
272
|
+
// Command name, args, and redirects (interleaved)
|
|
273
|
+
createArrayParser(bashWordOrRedirectParser),
|
|
274
|
+
]),
|
|
275
|
+
([assignments, items]) => {
|
|
276
|
+
const words: BashWord[] = [];
|
|
277
|
+
const redirects: BashRedirect[] = [];
|
|
278
|
+
|
|
279
|
+
for (const item of items) {
|
|
280
|
+
if (item.type === 'word') {
|
|
281
|
+
words.push(item.word);
|
|
282
|
+
} else {
|
|
283
|
+
redirects.push(item.redirect);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
const [name, ...args] = words;
|
|
288
|
+
|
|
289
|
+
return {
|
|
290
|
+
type: 'simple' as const,
|
|
291
|
+
name,
|
|
292
|
+
args,
|
|
293
|
+
redirects,
|
|
294
|
+
assignments,
|
|
295
|
+
};
|
|
296
|
+
},
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
setParserName(bashSimpleCommandParser, 'bashSimpleCommandParser');
|
|
300
|
+
|
|
301
|
+
// Subshell: ( command )
|
|
302
|
+
const bashSubshellParser: Parser<BashSubshell, string> = promiseCompose(
|
|
303
|
+
createTupleParser([
|
|
304
|
+
createExactSequenceParser('('),
|
|
305
|
+
bashOptionalInlineWhitespaceParser,
|
|
306
|
+
createParserAccessorParser(() => bashCommandParser),
|
|
307
|
+
bashOptionalInlineWhitespaceParser,
|
|
308
|
+
createExactSequenceParser(')'),
|
|
309
|
+
]),
|
|
310
|
+
([, , body]) => ({
|
|
311
|
+
type: 'subshell' as const,
|
|
312
|
+
body,
|
|
313
|
+
}),
|
|
314
|
+
);
|
|
315
|
+
|
|
316
|
+
setParserName(bashSubshellParser, 'bashSubshellParser');
|
|
317
|
+
|
|
318
|
+
// Brace group: { command; }
|
|
319
|
+
const bashBraceGroupParser: Parser<BashBraceGroup, string> = promiseCompose(
|
|
320
|
+
createTupleParser([
|
|
321
|
+
createExactSequenceParser('{'),
|
|
322
|
+
bashInlineWhitespaceParser,
|
|
323
|
+
createParserAccessorParser(() => bashCommandParser),
|
|
324
|
+
bashOptionalInlineWhitespaceParser,
|
|
325
|
+
createOptionalParser(createExactSequenceParser(';')),
|
|
326
|
+
bashOptionalInlineWhitespaceParser,
|
|
327
|
+
createExactSequenceParser('}'),
|
|
328
|
+
]),
|
|
329
|
+
([, , body]) => ({
|
|
330
|
+
type: 'braceGroup' as const,
|
|
331
|
+
body,
|
|
332
|
+
}),
|
|
333
|
+
);
|
|
334
|
+
|
|
335
|
+
setParserName(bashBraceGroupParser, 'bashBraceGroupParser');
|
|
336
|
+
|
|
337
|
+
// Command unit: simple command, subshell, or brace group
|
|
338
|
+
const bashCommandUnitParser: Parser<BashCommandUnit, string> = createDisjunctionParser([
|
|
339
|
+
bashSubshellParser,
|
|
340
|
+
bashBraceGroupParser,
|
|
341
|
+
bashSimpleCommandParser,
|
|
342
|
+
]);
|
|
343
|
+
|
|
344
|
+
setParserName(bashCommandUnitParser, 'bashCommandUnitParser');
|
|
345
|
+
|
|
346
|
+
// Single pipe (not ||) - matches | only when not followed by another |
|
|
347
|
+
const bashSinglePipeParser: Parser<string, string> = promiseCompose(
|
|
348
|
+
createRegExpParser(/\|(?!\|)/),
|
|
349
|
+
match => match[0],
|
|
350
|
+
);
|
|
351
|
+
|
|
352
|
+
// Pipeline: [!] cmd [| cmd]...
|
|
353
|
+
const bashPipelineParser: Parser<BashPipeline, string> = promiseCompose(
|
|
354
|
+
createTupleParser([
|
|
355
|
+
createOptionalParser(promiseCompose(
|
|
356
|
+
createTupleParser([
|
|
357
|
+
createExactSequenceParser('!'),
|
|
358
|
+
bashInlineWhitespaceParser,
|
|
359
|
+
]),
|
|
360
|
+
() => true,
|
|
361
|
+
)),
|
|
362
|
+
createSeparatedNonEmptyArrayParser(
|
|
363
|
+
bashCommandUnitParser,
|
|
364
|
+
createTupleParser([
|
|
365
|
+
bashOptionalInlineWhitespaceParser,
|
|
366
|
+
bashSinglePipeParser,
|
|
367
|
+
bashOptionalInlineWhitespaceParser,
|
|
368
|
+
]),
|
|
369
|
+
),
|
|
370
|
+
]),
|
|
371
|
+
([negated, commands]) => ({
|
|
372
|
+
type: 'pipeline' as const,
|
|
373
|
+
negated: negated ?? false,
|
|
374
|
+
commands,
|
|
375
|
+
}),
|
|
376
|
+
);
|
|
377
|
+
|
|
378
|
+
setParserName(bashPipelineParser, 'bashPipelineParser');
|
|
379
|
+
|
|
380
|
+
// Command list separator
|
|
381
|
+
const bashListSeparatorParser: Parser<'&&' | '||' | ';' | '&' | '\n', string> = createDisjunctionParser([
|
|
382
|
+
promiseCompose(createExactSequenceParser('&&'), () => '&&' as const),
|
|
383
|
+
promiseCompose(createExactSequenceParser('||'), () => '||' as const),
|
|
384
|
+
promiseCompose(createExactSequenceParser(';'), () => ';' as const),
|
|
385
|
+
promiseCompose(createExactSequenceParser('&'), () => '&' as const),
|
|
386
|
+
promiseCompose(bashNewlineParser, () => '\n' as const),
|
|
387
|
+
]);
|
|
388
|
+
|
|
389
|
+
// Command list: pipeline [sep pipeline]...
|
|
390
|
+
const bashCommandListParser: Parser<BashCommandList, string> = promiseCompose(
|
|
391
|
+
createTupleParser([
|
|
392
|
+
bashPipelineParser,
|
|
393
|
+
createArrayParser(promiseCompose(
|
|
394
|
+
createTupleParser([
|
|
395
|
+
bashOptionalInlineWhitespaceParser,
|
|
396
|
+
bashListSeparatorParser,
|
|
397
|
+
bashOptionalInlineWhitespaceParser,
|
|
398
|
+
bashPipelineParser,
|
|
399
|
+
]),
|
|
400
|
+
([, separator, , pipeline]) => ({ separator, pipeline }),
|
|
401
|
+
)),
|
|
402
|
+
createOptionalParser(promiseCompose(
|
|
403
|
+
createTupleParser([
|
|
404
|
+
bashOptionalInlineWhitespaceParser,
|
|
405
|
+
bashListSeparatorParser,
|
|
406
|
+
]),
|
|
407
|
+
([, separator]) => separator,
|
|
408
|
+
)),
|
|
409
|
+
]),
|
|
410
|
+
([firstPipeline, rest, trailingSeparator]) => {
|
|
411
|
+
const entries: BashCommandList['entries'] = [];
|
|
412
|
+
|
|
413
|
+
if (rest.length === 0) {
|
|
414
|
+
entries.push({
|
|
415
|
+
pipeline: firstPipeline,
|
|
416
|
+
separator: trailingSeparator ?? undefined,
|
|
417
|
+
});
|
|
418
|
+
} else {
|
|
419
|
+
entries.push({
|
|
420
|
+
pipeline: firstPipeline,
|
|
421
|
+
separator: rest[0].separator,
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
for (let i = 0; i < rest.length - 1; i++) {
|
|
425
|
+
entries.push({
|
|
426
|
+
pipeline: rest[i].pipeline,
|
|
427
|
+
separator: rest[i + 1].separator,
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
entries.push({
|
|
432
|
+
pipeline: rest[rest.length - 1].pipeline,
|
|
433
|
+
separator: trailingSeparator ?? undefined,
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
return {
|
|
438
|
+
type: 'list' as const,
|
|
439
|
+
entries,
|
|
440
|
+
};
|
|
441
|
+
},
|
|
442
|
+
);
|
|
443
|
+
|
|
444
|
+
setParserName(bashCommandListParser, 'bashCommandListParser');
|
|
445
|
+
|
|
446
|
+
// Top-level command parser
|
|
447
|
+
export const bashCommandParser: Parser<BashCommand, string> = bashCommandListParser;
|
|
448
|
+
|
|
449
|
+
setParserName(bashCommandParser, 'bashCommandParser');
|
|
450
|
+
|
|
451
|
+
// Script parser (handles leading/trailing whitespace)
|
|
452
|
+
export const bashScriptParser: Parser<BashCommand, string> = promiseCompose(
|
|
453
|
+
createTupleParser([
|
|
454
|
+
bashOptionalInlineWhitespaceParser,
|
|
455
|
+
bashCommandParser,
|
|
456
|
+
bashOptionalInlineWhitespaceParser,
|
|
457
|
+
]),
|
|
458
|
+
([, command]) => command,
|
|
459
|
+
);
|
|
460
|
+
|
|
461
|
+
setParserName(bashScriptParser, 'bashScriptParser');
|
package/src/index.ts
CHANGED
|
@@ -1,16 +1,59 @@
|
|
|
1
|
-
|
|
2
1
|
export {
|
|
3
2
|
type Parser,
|
|
4
3
|
runParser,
|
|
5
|
-
|
|
4
|
+
runParserWithRemainingInput,
|
|
6
5
|
setParserName,
|
|
7
6
|
getParserName,
|
|
7
|
+
cloneParser,
|
|
8
|
+
type RunParserOptions,
|
|
9
|
+
type RunParserWithRemainingInputResult,
|
|
8
10
|
} from './parser.js';
|
|
9
11
|
|
|
10
12
|
export type {
|
|
11
13
|
ParserContext,
|
|
12
14
|
} from './parserContext.js';
|
|
13
15
|
|
|
16
|
+
export {
|
|
17
|
+
type ParserInputCompanion,
|
|
18
|
+
StringParserInputCompanion,
|
|
19
|
+
stringParserInputCompanion,
|
|
20
|
+
Uint8ArrayParserInputCompanion,
|
|
21
|
+
uint8ArrayParserInputCompanion,
|
|
22
|
+
} from './parserInputCompanion.js';
|
|
23
|
+
|
|
24
|
+
export {
|
|
25
|
+
type UnparserOutputCompanion,
|
|
26
|
+
StringUnparserOutputCompanion,
|
|
27
|
+
stringUnparserOutputCompanion,
|
|
28
|
+
Uint8ArrayUnparserOutputCompanion,
|
|
29
|
+
uint8ArrayUnparserOutputCompanion,
|
|
30
|
+
} from './unparserOutputCompanion.js';
|
|
31
|
+
|
|
32
|
+
export {
|
|
33
|
+
type ParserError,
|
|
34
|
+
type ParserParsingFailedError,
|
|
35
|
+
type ParserParsingJoinError,
|
|
36
|
+
type ParserErrorModule,
|
|
37
|
+
isParserError,
|
|
38
|
+
isParserParsingFailedError,
|
|
39
|
+
isParserParsingJoinError,
|
|
40
|
+
normalParserErrorModule,
|
|
41
|
+
noStackCaptureOverheadParserErrorModule,
|
|
42
|
+
} from './parserError.js';
|
|
43
|
+
|
|
44
|
+
export {
|
|
45
|
+
parserCreatorCompose,
|
|
46
|
+
parserCreatorComposeMem,
|
|
47
|
+
} from './parserCreatorCompose.js';
|
|
48
|
+
|
|
49
|
+
export {
|
|
50
|
+
promiseCompose,
|
|
51
|
+
} from './promiseCompose.js';
|
|
52
|
+
|
|
53
|
+
export type {
|
|
54
|
+
DeriveSequenceElement,
|
|
55
|
+
} from './sequence.js';
|
|
56
|
+
|
|
14
57
|
export {
|
|
15
58
|
createTupleParser,
|
|
16
59
|
} from './tupleParser.js';
|
|
@@ -75,11 +118,75 @@ export {
|
|
|
75
118
|
createDebugLogParser,
|
|
76
119
|
} from './debugLogParser.js';
|
|
77
120
|
|
|
121
|
+
export {
|
|
122
|
+
createNonEmptyArrayParser,
|
|
123
|
+
} from './nonEmptyArrayParser.js';
|
|
124
|
+
|
|
125
|
+
export {
|
|
126
|
+
createSeparatedArrayParser,
|
|
127
|
+
} from './separatedArrayParser.js';
|
|
128
|
+
|
|
129
|
+
export {
|
|
130
|
+
createSeparatedNonEmptyArrayParser,
|
|
131
|
+
} from './separatedNonEmptyArrayParser.js';
|
|
132
|
+
|
|
133
|
+
export {
|
|
134
|
+
createLookaheadParser,
|
|
135
|
+
} from './lookaheadParser.js';
|
|
136
|
+
|
|
137
|
+
export {
|
|
138
|
+
createNegativeLookaheadParser,
|
|
139
|
+
} from './negativeLookaheadParser.js';
|
|
140
|
+
|
|
141
|
+
export {
|
|
142
|
+
createElementTerminatedSequenceParser,
|
|
143
|
+
} from './elementTerminatedSequenceParser.js';
|
|
144
|
+
|
|
145
|
+
export {
|
|
146
|
+
createElementTerminatedSequenceArrayParser,
|
|
147
|
+
} from './elementTerminatedSequenceArrayParser.js';
|
|
148
|
+
|
|
149
|
+
export {
|
|
150
|
+
createElementTerminatedArrayParserUnsafe,
|
|
151
|
+
} from './elementTerminatedArrayParser.js';
|
|
152
|
+
|
|
153
|
+
export {
|
|
154
|
+
createSequenceTerminatedSequenceParser,
|
|
155
|
+
} from './sequenceTerminatedSequenceParser.js';
|
|
156
|
+
|
|
157
|
+
export {
|
|
158
|
+
createQuantifierParser,
|
|
159
|
+
} from './quantifierParser.js';
|
|
160
|
+
|
|
161
|
+
export {
|
|
162
|
+
createSkipToParser,
|
|
163
|
+
} from './skipToParser.js';
|
|
164
|
+
|
|
165
|
+
export {
|
|
166
|
+
createDebugLogInputParser,
|
|
167
|
+
} from './debugLogInputParser.js';
|
|
168
|
+
|
|
169
|
+
export {
|
|
170
|
+
createElementSwitchParser,
|
|
171
|
+
} from './exactElementSwitchParser.js';
|
|
172
|
+
|
|
173
|
+
export {
|
|
174
|
+
createParserConsumedSequenceParser,
|
|
175
|
+
} from './parserConsumedSequenceParser.js';
|
|
176
|
+
|
|
78
177
|
export {
|
|
79
178
|
type Unparser,
|
|
179
|
+
type UnparserResult,
|
|
80
180
|
runUnparser,
|
|
81
181
|
} from './unparser.js';
|
|
82
182
|
|
|
183
|
+
export {
|
|
184
|
+
type UnparserContext,
|
|
185
|
+
WriteLater,
|
|
186
|
+
WriteEarlier,
|
|
187
|
+
UnparserContextImplementation,
|
|
188
|
+
} from './unparserContext.js';
|
|
189
|
+
|
|
83
190
|
export {
|
|
84
191
|
createArrayUnparser,
|
|
85
192
|
} from './arrayUnparser.js';
|
|
@@ -87,3 +194,7 @@ export {
|
|
|
87
194
|
export {
|
|
88
195
|
createSequenceUnparser,
|
|
89
196
|
} from './sequenceUnparser.js';
|
|
197
|
+
|
|
198
|
+
export {
|
|
199
|
+
createRegExpParser,
|
|
200
|
+
} from './regexpParser.js';
|