parseman 0.23.0 → 0.25.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 +1 -1
- 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/cst/relative-spans.d.ts +32 -0
- package/dist/cst/relative-spans.d.ts.map +1 -1
- package/dist/functional/doc.d.ts +53 -3
- package/dist/functional/doc.d.ts.map +1 -1
- package/dist/index.cjs +475 -139
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +475 -139
- package/dist/index.js.map +4 -4
- 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 +1038 -0
- package/dist/spec/index.cjs.map +7 -0
- package/dist/spec/index.d.ts +23 -0
- package/dist/spec/index.d.ts.map +1 -0
- package/dist/spec/index.js +1015 -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 +30 -0
- package/dist/spec/railroad.d.ts.map +1 -0
- package/package.json +8 -2
package/dist/plugin/index.js
CHANGED
|
@@ -387,24 +387,35 @@ function literal(value, opts = {}) {
|
|
|
387
387
|
{ lo: firstUpper, hi: firstUpper }
|
|
388
388
|
] } : firstSet2;
|
|
389
389
|
}
|
|
390
|
+
const expected = [JSON.stringify(value)];
|
|
391
|
+
const parse2 = !caseInsensitive && value.length === 1 ? (() => {
|
|
392
|
+
const code = value.charCodeAt(0);
|
|
393
|
+
return function parse3(input, pos, ctx) {
|
|
394
|
+
if (input.charCodeAt(pos) === code) {
|
|
395
|
+
const span = { start: pos, end: pos + 1 };
|
|
396
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
397
|
+
return { ok: true, value, span };
|
|
398
|
+
}
|
|
399
|
+
return failAt(ctx, expected, pos);
|
|
400
|
+
};
|
|
401
|
+
})() : function parse3(input, pos, ctx) {
|
|
402
|
+
const end = pos + value.length;
|
|
403
|
+
if (end > input.length) {
|
|
404
|
+
return failAt(ctx, expected, pos);
|
|
405
|
+
}
|
|
406
|
+
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
407
|
+
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
408
|
+
const span = { start: pos, end };
|
|
409
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: matchedValue, span });
|
|
410
|
+
return { ok: true, value: matchedValue, span };
|
|
411
|
+
}
|
|
412
|
+
return failAt(ctx, expected, pos);
|
|
413
|
+
};
|
|
390
414
|
return {
|
|
391
415
|
_tag: "literal",
|
|
392
416
|
_meta: meta,
|
|
393
417
|
_def: { tag: "literal", value, caseInsensitive },
|
|
394
|
-
parse
|
|
395
|
-
const end = pos + value.length;
|
|
396
|
-
if (end > input.length) {
|
|
397
|
-
return failAt(ctx, [JSON.stringify(value)], pos);
|
|
398
|
-
}
|
|
399
|
-
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
400
|
-
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
401
|
-
const span = { start: pos, end };
|
|
402
|
-
const leaf = { _tag: "leaf", value: matchedValue, span };
|
|
403
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, leaf);
|
|
404
|
-
return { ok: true, value: matchedValue, span };
|
|
405
|
-
}
|
|
406
|
-
return failAt(ctx, [JSON.stringify(value)], pos);
|
|
407
|
-
}
|
|
418
|
+
parse: parse2
|
|
408
419
|
};
|
|
409
420
|
}
|
|
410
421
|
|
|
@@ -539,8 +550,7 @@ function regex(pattern, flags = "") {
|
|
|
539
550
|
if (scanEnd === null) return failAt(ctx, [`/${source}/`], pos);
|
|
540
551
|
const value = input.slice(pos, scanEnd);
|
|
541
552
|
const span2 = { start: pos, end: scanEnd };
|
|
542
|
-
|
|
543
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, leaf2);
|
|
553
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span: span2 });
|
|
544
554
|
return { ok: true, value, span: span2 };
|
|
545
555
|
}
|
|
546
556
|
anchored.lastIndex = pos;
|
|
@@ -549,8 +559,7 @@ function regex(pattern, flags = "") {
|
|
|
549
559
|
return failAt(ctx, [`/${source}/`], pos);
|
|
550
560
|
}
|
|
551
561
|
const span = { start: pos, end: pos + m[0].length };
|
|
552
|
-
|
|
553
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, leaf);
|
|
562
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: m[0], span });
|
|
554
563
|
return { ok: true, value: m[0], span };
|
|
555
564
|
}
|
|
556
565
|
};
|
|
@@ -855,8 +864,7 @@ function keywords(words, opts = {}) {
|
|
|
855
864
|
}
|
|
856
865
|
const value = m[0];
|
|
857
866
|
const span = { start: pos, end: pos + value.length };
|
|
858
|
-
|
|
859
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, leaf);
|
|
867
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
860
868
|
return { ok: true, value, span };
|
|
861
869
|
}
|
|
862
870
|
};
|
|
@@ -1346,33 +1354,136 @@ function loopScanner(arms) {
|
|
|
1346
1354
|
}
|
|
1347
1355
|
function regexTriviaScanner(parser2) {
|
|
1348
1356
|
if (parser2._def.tag !== "regex" || parser2._def.flags) return null;
|
|
1349
|
-
const
|
|
1350
|
-
|
|
1351
|
-
return blockCommentSource(parser2._def.source) ? scanBlockComment : null;
|
|
1357
|
+
const source = parser2._def.source;
|
|
1358
|
+
return classRunSource(source) ?? altStarSource(source) ?? (blockCommentSource(source) ? scanBlockComment : null);
|
|
1352
1359
|
}
|
|
1353
|
-
function
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1360
|
+
function inRanges2(cp, ranges) {
|
|
1361
|
+
for (let i = 0; i < ranges.length; i++) {
|
|
1362
|
+
const r = ranges[i];
|
|
1363
|
+
if (cp >= r[0] && cp <= r[1]) return true;
|
|
1364
|
+
}
|
|
1365
|
+
return false;
|
|
1366
|
+
}
|
|
1367
|
+
function classScanner(classBody) {
|
|
1368
|
+
const ranges = parseClassRanges(classBody);
|
|
1369
|
+
if (!ranges) return null;
|
|
1370
|
+
return (input, cur) => {
|
|
1371
|
+
let pos = cur;
|
|
1372
|
+
while (pos < input.length && inRanges2(input.charCodeAt(pos), ranges)) pos++;
|
|
1373
|
+
return pos;
|
|
1374
|
+
};
|
|
1375
|
+
}
|
|
1376
|
+
function lineCommentScanner(commentCode) {
|
|
1377
|
+
return (input, cur) => {
|
|
1378
|
+
if (input.charCodeAt(cur) !== commentCode) return cur;
|
|
1379
|
+
let pos = cur + 1;
|
|
1380
|
+
while (pos < input.length) {
|
|
1381
|
+
const cc = input.charCodeAt(pos);
|
|
1382
|
+
if (cc === 10 || cc === 13) break;
|
|
1383
|
+
pos++;
|
|
1362
1384
|
}
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1385
|
+
return pos;
|
|
1386
|
+
};
|
|
1387
|
+
}
|
|
1388
|
+
function classRunSource(source) {
|
|
1389
|
+
const m = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]$/.exec(source);
|
|
1390
|
+
return m ? classScanner(m[1]) : null;
|
|
1391
|
+
}
|
|
1392
|
+
function classifyTriviaArm(arm) {
|
|
1393
|
+
const cls = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]?$/.exec(arm);
|
|
1394
|
+
if (cls) {
|
|
1395
|
+
const ranges = parseClassRanges(cls[1]);
|
|
1396
|
+
return ranges ? { kind: "class", ranges } : null;
|
|
1397
|
+
}
|
|
1398
|
+
const lc = /^(\\?.)\[\^\\n\\r\]\*$/.exec(arm);
|
|
1399
|
+
if (lc) {
|
|
1400
|
+
const marker = lc[1];
|
|
1401
|
+
return { kind: "comment", code: (marker.length === 2 ? marker[1] : marker[0]).charCodeAt(0) };
|
|
1369
1402
|
}
|
|
1403
|
+
return null;
|
|
1404
|
+
}
|
|
1405
|
+
function armScanner(arm) {
|
|
1406
|
+
if (arm.kind === "comment") return lineCommentScanner(arm.code);
|
|
1407
|
+
const ranges = arm.ranges;
|
|
1408
|
+
return (input, cur) => {
|
|
1409
|
+
let pos = cur;
|
|
1410
|
+
while (pos < input.length && inRanges2(input.charCodeAt(pos), ranges)) pos++;
|
|
1411
|
+
return pos;
|
|
1412
|
+
};
|
|
1413
|
+
}
|
|
1414
|
+
function fusedTriviaScanner(ranges, commentCodes) {
|
|
1415
|
+
const c0 = commentCodes[0];
|
|
1416
|
+
const single = commentCodes.length === 1;
|
|
1370
1417
|
return (input, cur) => {
|
|
1371
1418
|
let pos = cur;
|
|
1372
|
-
|
|
1419
|
+
const len = input.length;
|
|
1420
|
+
for (; ; ) {
|
|
1421
|
+
const c = input.charCodeAt(pos);
|
|
1422
|
+
if (pos < len && inRanges2(c, ranges)) {
|
|
1423
|
+
pos++;
|
|
1424
|
+
continue;
|
|
1425
|
+
}
|
|
1426
|
+
if (single ? c === c0 : commentCodes.includes(c)) {
|
|
1427
|
+
pos++;
|
|
1428
|
+
while (pos < len) {
|
|
1429
|
+
const cc = input.charCodeAt(pos);
|
|
1430
|
+
if (cc === 10 || cc === 13) break;
|
|
1431
|
+
pos++;
|
|
1432
|
+
}
|
|
1433
|
+
continue;
|
|
1434
|
+
}
|
|
1435
|
+
break;
|
|
1436
|
+
}
|
|
1373
1437
|
return pos;
|
|
1374
1438
|
};
|
|
1375
1439
|
}
|
|
1440
|
+
function splitTopLevelAlts(body) {
|
|
1441
|
+
const arms = [];
|
|
1442
|
+
let inClass = false;
|
|
1443
|
+
let start = 0;
|
|
1444
|
+
for (let i = 0; i < body.length; i++) {
|
|
1445
|
+
const c = body[i];
|
|
1446
|
+
if (c === "\\") {
|
|
1447
|
+
i++;
|
|
1448
|
+
continue;
|
|
1449
|
+
}
|
|
1450
|
+
if (inClass) {
|
|
1451
|
+
if (c === "]") inClass = false;
|
|
1452
|
+
continue;
|
|
1453
|
+
}
|
|
1454
|
+
if (c === "[") inClass = true;
|
|
1455
|
+
else if (c === "(") return null;
|
|
1456
|
+
else if (c === "|") {
|
|
1457
|
+
arms.push(body.slice(start, i));
|
|
1458
|
+
start = i + 1;
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
arms.push(body.slice(start));
|
|
1462
|
+
return arms;
|
|
1463
|
+
}
|
|
1464
|
+
function altStarSource(source) {
|
|
1465
|
+
const m = /^\(\?:(.*)\)[*+]$/.exec(source);
|
|
1466
|
+
if (!m) return null;
|
|
1467
|
+
const armSrcs = splitTopLevelAlts(m[1]);
|
|
1468
|
+
if (!armSrcs || armSrcs.length < 2) return null;
|
|
1469
|
+
const arms = [];
|
|
1470
|
+
for (const src of armSrcs) {
|
|
1471
|
+
const arm = classifyTriviaArm(src);
|
|
1472
|
+
if (!arm) return null;
|
|
1473
|
+
arms.push(arm);
|
|
1474
|
+
}
|
|
1475
|
+
const ranges = [];
|
|
1476
|
+
const commentCodes = [];
|
|
1477
|
+
for (const arm of arms) {
|
|
1478
|
+
if (arm.kind === "class") ranges.push(...arm.ranges);
|
|
1479
|
+
else commentCodes.push(arm.code);
|
|
1480
|
+
}
|
|
1481
|
+
if (commentCodes.some((code) => inRanges2(code, ranges))) {
|
|
1482
|
+
return loopScanner(arms.map(armScanner));
|
|
1483
|
+
}
|
|
1484
|
+
if (commentCodes.length === 0) return armScanner({ kind: "class", ranges });
|
|
1485
|
+
return fusedTriviaScanner(ranges, commentCodes);
|
|
1486
|
+
}
|
|
1376
1487
|
function blockCommentSource(source) {
|
|
1377
1488
|
return source === "\\/\\*(?:[^*]|\\*(?!\\/))*\\*\\/" || source === "\\/\\*[^]*?\\*\\/";
|
|
1378
1489
|
}
|
|
@@ -1689,6 +1800,7 @@ function markUnusedValues(root) {
|
|
|
1689
1800
|
}
|
|
1690
1801
|
|
|
1691
1802
|
// src/combinators/parser.ts
|
|
1803
|
+
var RULE_ORDER = "__parsemanRuleOrder";
|
|
1692
1804
|
function tagRule(r, key) {
|
|
1693
1805
|
;
|
|
1694
1806
|
r._ruleName = key;
|
|
@@ -1733,6 +1845,11 @@ function rules(a, b) {
|
|
|
1733
1845
|
for (const key of Object.keys(definitions)) {
|
|
1734
1846
|
markUnusedValues(cache[key]);
|
|
1735
1847
|
}
|
|
1848
|
+
Object.defineProperty(cache, RULE_ORDER, {
|
|
1849
|
+
value: Object.keys(definitions),
|
|
1850
|
+
enumerable: false,
|
|
1851
|
+
configurable: true
|
|
1852
|
+
});
|
|
1736
1853
|
return cache;
|
|
1737
1854
|
}
|
|
1738
1855
|
|