parseman 0.23.0 → 0.24.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/dist/combinators/keywords.d.ts.map +1 -1
- package/dist/combinators/literal.d.ts.map +1 -1
- package/dist/combinators/parser.d.ts +6 -0
- package/dist/combinators/parser.d.ts.map +1 -1
- package/dist/combinators/regex.d.ts.map +1 -1
- package/dist/combinators/trivia-skip.d.ts.map +1 -1
- package/dist/index.cjs +156 -39
- package/dist/index.cjs.map +3 -3
- package/dist/index.js +156 -39
- package/dist/index.js.map +3 -3
- package/dist/plugin/index.cjs +156 -39
- package/dist/plugin/index.cjs.map +3 -3
- package/dist/plugin/index.js +156 -39
- package/dist/plugin/index.js.map +3 -3
- package/dist/spec/ebnf.d.ts +13 -0
- package/dist/spec/ebnf.d.ts.map +1 -0
- package/dist/spec/index.cjs +977 -0
- package/dist/spec/index.cjs.map +7 -0
- package/dist/spec/index.d.ts +15 -0
- package/dist/spec/index.d.ts.map +1 -0
- package/dist/spec/index.js +954 -0
- package/dist/spec/index.js.map +7 -0
- package/dist/spec/model.d.ts +117 -0
- package/dist/spec/model.d.ts.map +1 -0
- package/dist/spec/railroad-lib.d.ts +11 -0
- package/dist/spec/railroad-lib.d.ts.map +1 -0
- package/dist/spec/railroad.d.ts +18 -0
- package/dist/spec/railroad.d.ts.map +1 -0
- package/package.json +6 -1
package/dist/index.js
CHANGED
|
@@ -343,24 +343,35 @@ function literal(value, opts = {}) {
|
|
|
343
343
|
{ lo: firstUpper, hi: firstUpper }
|
|
344
344
|
] } : firstSet2;
|
|
345
345
|
}
|
|
346
|
+
const expected = [JSON.stringify(value)];
|
|
347
|
+
const parse2 = !caseInsensitive && value.length === 1 ? (() => {
|
|
348
|
+
const code = value.charCodeAt(0);
|
|
349
|
+
return function parse3(input, pos, ctx) {
|
|
350
|
+
if (input.charCodeAt(pos) === code) {
|
|
351
|
+
const span = { start: pos, end: pos + 1 };
|
|
352
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
353
|
+
return { ok: true, value, span };
|
|
354
|
+
}
|
|
355
|
+
return failAt(ctx, expected, pos);
|
|
356
|
+
};
|
|
357
|
+
})() : function parse3(input, pos, ctx) {
|
|
358
|
+
const end = pos + value.length;
|
|
359
|
+
if (end > input.length) {
|
|
360
|
+
return failAt(ctx, expected, pos);
|
|
361
|
+
}
|
|
362
|
+
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
363
|
+
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
364
|
+
const span = { start: pos, end };
|
|
365
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: matchedValue, span });
|
|
366
|
+
return { ok: true, value: matchedValue, span };
|
|
367
|
+
}
|
|
368
|
+
return failAt(ctx, expected, pos);
|
|
369
|
+
};
|
|
346
370
|
return {
|
|
347
371
|
_tag: "literal",
|
|
348
372
|
_meta: meta,
|
|
349
373
|
_def: { tag: "literal", value, caseInsensitive },
|
|
350
|
-
parse
|
|
351
|
-
const end = pos + value.length;
|
|
352
|
-
if (end > input.length) {
|
|
353
|
-
return failAt(ctx, [JSON.stringify(value)], pos);
|
|
354
|
-
}
|
|
355
|
-
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
356
|
-
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
357
|
-
const span = { start: pos, end };
|
|
358
|
-
const leaf = { _tag: "leaf", value: matchedValue, span };
|
|
359
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, leaf);
|
|
360
|
-
return { ok: true, value: matchedValue, span };
|
|
361
|
-
}
|
|
362
|
-
return failAt(ctx, [JSON.stringify(value)], pos);
|
|
363
|
-
}
|
|
374
|
+
parse: parse2
|
|
364
375
|
};
|
|
365
376
|
}
|
|
366
377
|
|
|
@@ -495,8 +506,7 @@ function regex(pattern, flags = "") {
|
|
|
495
506
|
if (scanEnd === null) return failAt(ctx, [`/${source}/`], pos);
|
|
496
507
|
const value = input.slice(pos, scanEnd);
|
|
497
508
|
const span2 = { start: pos, end: scanEnd };
|
|
498
|
-
|
|
499
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, leaf2);
|
|
509
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span: span2 });
|
|
500
510
|
return { ok: true, value, span: span2 };
|
|
501
511
|
}
|
|
502
512
|
anchored.lastIndex = pos;
|
|
@@ -505,8 +515,7 @@ function regex(pattern, flags = "") {
|
|
|
505
515
|
return failAt(ctx, [`/${source}/`], pos);
|
|
506
516
|
}
|
|
507
517
|
const span = { start: pos, end: pos + m[0].length };
|
|
508
|
-
|
|
509
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, leaf);
|
|
518
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: m[0], span });
|
|
510
519
|
return { ok: true, value: m[0], span };
|
|
511
520
|
}
|
|
512
521
|
};
|
|
@@ -814,8 +823,7 @@ function keywords(words, opts = {}) {
|
|
|
814
823
|
}
|
|
815
824
|
const value = m[0];
|
|
816
825
|
const span = { start: pos, end: pos + value.length };
|
|
817
|
-
|
|
818
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, leaf);
|
|
826
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
819
827
|
return { ok: true, value, span };
|
|
820
828
|
}
|
|
821
829
|
};
|
|
@@ -1305,33 +1313,136 @@ function loopScanner(arms) {
|
|
|
1305
1313
|
}
|
|
1306
1314
|
function regexTriviaScanner(parser2) {
|
|
1307
1315
|
if (parser2._def.tag !== "regex" || parser2._def.flags) return null;
|
|
1308
|
-
const
|
|
1309
|
-
|
|
1310
|
-
return blockCommentSource(parser2._def.source) ? scanBlockComment : null;
|
|
1316
|
+
const source = parser2._def.source;
|
|
1317
|
+
return classRunSource(source) ?? altStarSource(source) ?? (blockCommentSource(source) ? scanBlockComment : null);
|
|
1311
1318
|
}
|
|
1312
|
-
function
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1319
|
+
function inRanges2(cp, ranges) {
|
|
1320
|
+
for (let i = 0; i < ranges.length; i++) {
|
|
1321
|
+
const r = ranges[i];
|
|
1322
|
+
if (cp >= r[0] && cp <= r[1]) return true;
|
|
1323
|
+
}
|
|
1324
|
+
return false;
|
|
1325
|
+
}
|
|
1326
|
+
function classScanner(classBody) {
|
|
1327
|
+
const ranges = parseClassRanges(classBody);
|
|
1328
|
+
if (!ranges) return null;
|
|
1329
|
+
return (input, cur) => {
|
|
1330
|
+
let pos = cur;
|
|
1331
|
+
while (pos < input.length && inRanges2(input.charCodeAt(pos), ranges)) pos++;
|
|
1332
|
+
return pos;
|
|
1333
|
+
};
|
|
1334
|
+
}
|
|
1335
|
+
function lineCommentScanner(commentCode) {
|
|
1336
|
+
return (input, cur) => {
|
|
1337
|
+
if (input.charCodeAt(cur) !== commentCode) return cur;
|
|
1338
|
+
let pos = cur + 1;
|
|
1339
|
+
while (pos < input.length) {
|
|
1340
|
+
const cc = input.charCodeAt(pos);
|
|
1341
|
+
if (cc === 10 || cc === 13) break;
|
|
1342
|
+
pos++;
|
|
1321
1343
|
}
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1344
|
+
return pos;
|
|
1345
|
+
};
|
|
1346
|
+
}
|
|
1347
|
+
function classRunSource(source) {
|
|
1348
|
+
const m = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]$/.exec(source);
|
|
1349
|
+
return m ? classScanner(m[1]) : null;
|
|
1350
|
+
}
|
|
1351
|
+
function classifyTriviaArm(arm) {
|
|
1352
|
+
const cls = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]?$/.exec(arm);
|
|
1353
|
+
if (cls) {
|
|
1354
|
+
const ranges = parseClassRanges(cls[1]);
|
|
1355
|
+
return ranges ? { kind: "class", ranges } : null;
|
|
1356
|
+
}
|
|
1357
|
+
const lc = /^(\\?.)\[\^\\n\\r\]\*$/.exec(arm);
|
|
1358
|
+
if (lc) {
|
|
1359
|
+
const marker = lc[1];
|
|
1360
|
+
return { kind: "comment", code: (marker.length === 2 ? marker[1] : marker[0]).charCodeAt(0) };
|
|
1328
1361
|
}
|
|
1362
|
+
return null;
|
|
1363
|
+
}
|
|
1364
|
+
function armScanner(arm) {
|
|
1365
|
+
if (arm.kind === "comment") return lineCommentScanner(arm.code);
|
|
1366
|
+
const ranges = arm.ranges;
|
|
1367
|
+
return (input, cur) => {
|
|
1368
|
+
let pos = cur;
|
|
1369
|
+
while (pos < input.length && inRanges2(input.charCodeAt(pos), ranges)) pos++;
|
|
1370
|
+
return pos;
|
|
1371
|
+
};
|
|
1372
|
+
}
|
|
1373
|
+
function fusedTriviaScanner(ranges, commentCodes) {
|
|
1374
|
+
const c0 = commentCodes[0];
|
|
1375
|
+
const single = commentCodes.length === 1;
|
|
1329
1376
|
return (input, cur) => {
|
|
1330
1377
|
let pos = cur;
|
|
1331
|
-
|
|
1378
|
+
const len = input.length;
|
|
1379
|
+
for (; ; ) {
|
|
1380
|
+
const c = input.charCodeAt(pos);
|
|
1381
|
+
if (pos < len && inRanges2(c, ranges)) {
|
|
1382
|
+
pos++;
|
|
1383
|
+
continue;
|
|
1384
|
+
}
|
|
1385
|
+
if (single ? c === c0 : commentCodes.includes(c)) {
|
|
1386
|
+
pos++;
|
|
1387
|
+
while (pos < len) {
|
|
1388
|
+
const cc = input.charCodeAt(pos);
|
|
1389
|
+
if (cc === 10 || cc === 13) break;
|
|
1390
|
+
pos++;
|
|
1391
|
+
}
|
|
1392
|
+
continue;
|
|
1393
|
+
}
|
|
1394
|
+
break;
|
|
1395
|
+
}
|
|
1332
1396
|
return pos;
|
|
1333
1397
|
};
|
|
1334
1398
|
}
|
|
1399
|
+
function splitTopLevelAlts(body) {
|
|
1400
|
+
const arms = [];
|
|
1401
|
+
let inClass = false;
|
|
1402
|
+
let start = 0;
|
|
1403
|
+
for (let i = 0; i < body.length; i++) {
|
|
1404
|
+
const c = body[i];
|
|
1405
|
+
if (c === "\\") {
|
|
1406
|
+
i++;
|
|
1407
|
+
continue;
|
|
1408
|
+
}
|
|
1409
|
+
if (inClass) {
|
|
1410
|
+
if (c === "]") inClass = false;
|
|
1411
|
+
continue;
|
|
1412
|
+
}
|
|
1413
|
+
if (c === "[") inClass = true;
|
|
1414
|
+
else if (c === "(") return null;
|
|
1415
|
+
else if (c === "|") {
|
|
1416
|
+
arms.push(body.slice(start, i));
|
|
1417
|
+
start = i + 1;
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
arms.push(body.slice(start));
|
|
1421
|
+
return arms;
|
|
1422
|
+
}
|
|
1423
|
+
function altStarSource(source) {
|
|
1424
|
+
const m = /^\(\?:(.*)\)[*+]$/.exec(source);
|
|
1425
|
+
if (!m) return null;
|
|
1426
|
+
const armSrcs = splitTopLevelAlts(m[1]);
|
|
1427
|
+
if (!armSrcs || armSrcs.length < 2) return null;
|
|
1428
|
+
const arms = [];
|
|
1429
|
+
for (const src of armSrcs) {
|
|
1430
|
+
const arm = classifyTriviaArm(src);
|
|
1431
|
+
if (!arm) return null;
|
|
1432
|
+
arms.push(arm);
|
|
1433
|
+
}
|
|
1434
|
+
const ranges = [];
|
|
1435
|
+
const commentCodes = [];
|
|
1436
|
+
for (const arm of arms) {
|
|
1437
|
+
if (arm.kind === "class") ranges.push(...arm.ranges);
|
|
1438
|
+
else commentCodes.push(arm.code);
|
|
1439
|
+
}
|
|
1440
|
+
if (commentCodes.some((code) => inRanges2(code, ranges))) {
|
|
1441
|
+
return loopScanner(arms.map(armScanner));
|
|
1442
|
+
}
|
|
1443
|
+
if (commentCodes.length === 0) return armScanner({ kind: "class", ranges });
|
|
1444
|
+
return fusedTriviaScanner(ranges, commentCodes);
|
|
1445
|
+
}
|
|
1335
1446
|
function blockCommentSource(source) {
|
|
1336
1447
|
return source === "\\/\\*(?:[^*]|\\*(?!\\/))*\\*\\/" || source === "\\/\\*[^]*?\\*\\/";
|
|
1337
1448
|
}
|
|
@@ -1685,6 +1796,7 @@ function markUnusedValues(root) {
|
|
|
1685
1796
|
}
|
|
1686
1797
|
|
|
1687
1798
|
// src/combinators/parser.ts
|
|
1799
|
+
var RULE_ORDER = "__parsemanRuleOrder";
|
|
1688
1800
|
function tagRule(r, key) {
|
|
1689
1801
|
;
|
|
1690
1802
|
r._ruleName = key;
|
|
@@ -1729,6 +1841,11 @@ function rules(a, b) {
|
|
|
1729
1841
|
for (const key of Object.keys(definitions)) {
|
|
1730
1842
|
markUnusedValues(cache[key]);
|
|
1731
1843
|
}
|
|
1844
|
+
Object.defineProperty(cache, RULE_ORDER, {
|
|
1845
|
+
value: Object.keys(definitions),
|
|
1846
|
+
enumerable: false,
|
|
1847
|
+
configurable: true
|
|
1848
|
+
});
|
|
1732
1849
|
return cache;
|
|
1733
1850
|
}
|
|
1734
1851
|
|