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/plugin/index.cjs
CHANGED
|
@@ -422,24 +422,35 @@ function literal(value, opts = {}) {
|
|
|
422
422
|
{ lo: firstUpper, hi: firstUpper }
|
|
423
423
|
] } : firstSet2;
|
|
424
424
|
}
|
|
425
|
+
const expected = [JSON.stringify(value)];
|
|
426
|
+
const parse2 = !caseInsensitive && value.length === 1 ? (() => {
|
|
427
|
+
const code = value.charCodeAt(0);
|
|
428
|
+
return function parse3(input, pos, ctx) {
|
|
429
|
+
if (input.charCodeAt(pos) === code) {
|
|
430
|
+
const span = { start: pos, end: pos + 1 };
|
|
431
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
432
|
+
return { ok: true, value, span };
|
|
433
|
+
}
|
|
434
|
+
return failAt(ctx, expected, pos);
|
|
435
|
+
};
|
|
436
|
+
})() : function parse3(input, pos, ctx) {
|
|
437
|
+
const end = pos + value.length;
|
|
438
|
+
if (end > input.length) {
|
|
439
|
+
return failAt(ctx, expected, pos);
|
|
440
|
+
}
|
|
441
|
+
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
442
|
+
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
443
|
+
const span = { start: pos, end };
|
|
444
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: matchedValue, span });
|
|
445
|
+
return { ok: true, value: matchedValue, span };
|
|
446
|
+
}
|
|
447
|
+
return failAt(ctx, expected, pos);
|
|
448
|
+
};
|
|
425
449
|
return {
|
|
426
450
|
_tag: "literal",
|
|
427
451
|
_meta: meta,
|
|
428
452
|
_def: { tag: "literal", value, caseInsensitive },
|
|
429
|
-
parse
|
|
430
|
-
const end = pos + value.length;
|
|
431
|
-
if (end > input.length) {
|
|
432
|
-
return failAt(ctx, [JSON.stringify(value)], pos);
|
|
433
|
-
}
|
|
434
|
-
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
435
|
-
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
436
|
-
const span = { start: pos, end };
|
|
437
|
-
const leaf = { _tag: "leaf", value: matchedValue, span };
|
|
438
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, leaf);
|
|
439
|
-
return { ok: true, value: matchedValue, span };
|
|
440
|
-
}
|
|
441
|
-
return failAt(ctx, [JSON.stringify(value)], pos);
|
|
442
|
-
}
|
|
453
|
+
parse: parse2
|
|
443
454
|
};
|
|
444
455
|
}
|
|
445
456
|
|
|
@@ -574,8 +585,7 @@ function regex(pattern, flags = "") {
|
|
|
574
585
|
if (scanEnd === null) return failAt(ctx, [`/${source}/`], pos);
|
|
575
586
|
const value = input.slice(pos, scanEnd);
|
|
576
587
|
const span2 = { start: pos, end: scanEnd };
|
|
577
|
-
|
|
578
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, leaf2);
|
|
588
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span: span2 });
|
|
579
589
|
return { ok: true, value, span: span2 };
|
|
580
590
|
}
|
|
581
591
|
anchored.lastIndex = pos;
|
|
@@ -584,8 +594,7 @@ function regex(pattern, flags = "") {
|
|
|
584
594
|
return failAt(ctx, [`/${source}/`], pos);
|
|
585
595
|
}
|
|
586
596
|
const span = { start: pos, end: pos + m[0].length };
|
|
587
|
-
|
|
588
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, leaf);
|
|
597
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: m[0], span });
|
|
589
598
|
return { ok: true, value: m[0], span };
|
|
590
599
|
}
|
|
591
600
|
};
|
|
@@ -890,8 +899,7 @@ function keywords(words, opts = {}) {
|
|
|
890
899
|
}
|
|
891
900
|
const value = m[0];
|
|
892
901
|
const span = { start: pos, end: pos + value.length };
|
|
893
|
-
|
|
894
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, leaf);
|
|
902
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
895
903
|
return { ok: true, value, span };
|
|
896
904
|
}
|
|
897
905
|
};
|
|
@@ -1381,33 +1389,136 @@ function loopScanner(arms) {
|
|
|
1381
1389
|
}
|
|
1382
1390
|
function regexTriviaScanner(parser2) {
|
|
1383
1391
|
if (parser2._def.tag !== "regex" || parser2._def.flags) return null;
|
|
1384
|
-
const
|
|
1385
|
-
|
|
1386
|
-
return blockCommentSource(parser2._def.source) ? scanBlockComment : null;
|
|
1392
|
+
const source = parser2._def.source;
|
|
1393
|
+
return classRunSource(source) ?? altStarSource(source) ?? (blockCommentSource(source) ? scanBlockComment : null);
|
|
1387
1394
|
}
|
|
1388
|
-
function
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1395
|
+
function inRanges2(cp, ranges) {
|
|
1396
|
+
for (let i = 0; i < ranges.length; i++) {
|
|
1397
|
+
const r = ranges[i];
|
|
1398
|
+
if (cp >= r[0] && cp <= r[1]) return true;
|
|
1399
|
+
}
|
|
1400
|
+
return false;
|
|
1401
|
+
}
|
|
1402
|
+
function classScanner(classBody) {
|
|
1403
|
+
const ranges = parseClassRanges(classBody);
|
|
1404
|
+
if (!ranges) return null;
|
|
1405
|
+
return (input, cur) => {
|
|
1406
|
+
let pos = cur;
|
|
1407
|
+
while (pos < input.length && inRanges2(input.charCodeAt(pos), ranges)) pos++;
|
|
1408
|
+
return pos;
|
|
1409
|
+
};
|
|
1410
|
+
}
|
|
1411
|
+
function lineCommentScanner(commentCode) {
|
|
1412
|
+
return (input, cur) => {
|
|
1413
|
+
if (input.charCodeAt(cur) !== commentCode) return cur;
|
|
1414
|
+
let pos = cur + 1;
|
|
1415
|
+
while (pos < input.length) {
|
|
1416
|
+
const cc = input.charCodeAt(pos);
|
|
1417
|
+
if (cc === 10 || cc === 13) break;
|
|
1418
|
+
pos++;
|
|
1397
1419
|
}
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1420
|
+
return pos;
|
|
1421
|
+
};
|
|
1422
|
+
}
|
|
1423
|
+
function classRunSource(source) {
|
|
1424
|
+
const m = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]$/.exec(source);
|
|
1425
|
+
return m ? classScanner(m[1]) : null;
|
|
1426
|
+
}
|
|
1427
|
+
function classifyTriviaArm(arm) {
|
|
1428
|
+
const cls = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]?$/.exec(arm);
|
|
1429
|
+
if (cls) {
|
|
1430
|
+
const ranges = parseClassRanges(cls[1]);
|
|
1431
|
+
return ranges ? { kind: "class", ranges } : null;
|
|
1432
|
+
}
|
|
1433
|
+
const lc = /^(\\?.)\[\^\\n\\r\]\*$/.exec(arm);
|
|
1434
|
+
if (lc) {
|
|
1435
|
+
const marker = lc[1];
|
|
1436
|
+
return { kind: "comment", code: (marker.length === 2 ? marker[1] : marker[0]).charCodeAt(0) };
|
|
1404
1437
|
}
|
|
1438
|
+
return null;
|
|
1439
|
+
}
|
|
1440
|
+
function armScanner(arm) {
|
|
1441
|
+
if (arm.kind === "comment") return lineCommentScanner(arm.code);
|
|
1442
|
+
const ranges = arm.ranges;
|
|
1443
|
+
return (input, cur) => {
|
|
1444
|
+
let pos = cur;
|
|
1445
|
+
while (pos < input.length && inRanges2(input.charCodeAt(pos), ranges)) pos++;
|
|
1446
|
+
return pos;
|
|
1447
|
+
};
|
|
1448
|
+
}
|
|
1449
|
+
function fusedTriviaScanner(ranges, commentCodes) {
|
|
1450
|
+
const c0 = commentCodes[0];
|
|
1451
|
+
const single = commentCodes.length === 1;
|
|
1405
1452
|
return (input, cur) => {
|
|
1406
1453
|
let pos = cur;
|
|
1407
|
-
|
|
1454
|
+
const len = input.length;
|
|
1455
|
+
for (; ; ) {
|
|
1456
|
+
const c = input.charCodeAt(pos);
|
|
1457
|
+
if (pos < len && inRanges2(c, ranges)) {
|
|
1458
|
+
pos++;
|
|
1459
|
+
continue;
|
|
1460
|
+
}
|
|
1461
|
+
if (single ? c === c0 : commentCodes.includes(c)) {
|
|
1462
|
+
pos++;
|
|
1463
|
+
while (pos < len) {
|
|
1464
|
+
const cc = input.charCodeAt(pos);
|
|
1465
|
+
if (cc === 10 || cc === 13) break;
|
|
1466
|
+
pos++;
|
|
1467
|
+
}
|
|
1468
|
+
continue;
|
|
1469
|
+
}
|
|
1470
|
+
break;
|
|
1471
|
+
}
|
|
1408
1472
|
return pos;
|
|
1409
1473
|
};
|
|
1410
1474
|
}
|
|
1475
|
+
function splitTopLevelAlts(body) {
|
|
1476
|
+
const arms = [];
|
|
1477
|
+
let inClass = false;
|
|
1478
|
+
let start = 0;
|
|
1479
|
+
for (let i = 0; i < body.length; i++) {
|
|
1480
|
+
const c = body[i];
|
|
1481
|
+
if (c === "\\") {
|
|
1482
|
+
i++;
|
|
1483
|
+
continue;
|
|
1484
|
+
}
|
|
1485
|
+
if (inClass) {
|
|
1486
|
+
if (c === "]") inClass = false;
|
|
1487
|
+
continue;
|
|
1488
|
+
}
|
|
1489
|
+
if (c === "[") inClass = true;
|
|
1490
|
+
else if (c === "(") return null;
|
|
1491
|
+
else if (c === "|") {
|
|
1492
|
+
arms.push(body.slice(start, i));
|
|
1493
|
+
start = i + 1;
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
arms.push(body.slice(start));
|
|
1497
|
+
return arms;
|
|
1498
|
+
}
|
|
1499
|
+
function altStarSource(source) {
|
|
1500
|
+
const m = /^\(\?:(.*)\)[*+]$/.exec(source);
|
|
1501
|
+
if (!m) return null;
|
|
1502
|
+
const armSrcs = splitTopLevelAlts(m[1]);
|
|
1503
|
+
if (!armSrcs || armSrcs.length < 2) return null;
|
|
1504
|
+
const arms = [];
|
|
1505
|
+
for (const src of armSrcs) {
|
|
1506
|
+
const arm = classifyTriviaArm(src);
|
|
1507
|
+
if (!arm) return null;
|
|
1508
|
+
arms.push(arm);
|
|
1509
|
+
}
|
|
1510
|
+
const ranges = [];
|
|
1511
|
+
const commentCodes = [];
|
|
1512
|
+
for (const arm of arms) {
|
|
1513
|
+
if (arm.kind === "class") ranges.push(...arm.ranges);
|
|
1514
|
+
else commentCodes.push(arm.code);
|
|
1515
|
+
}
|
|
1516
|
+
if (commentCodes.some((code) => inRanges2(code, ranges))) {
|
|
1517
|
+
return loopScanner(arms.map(armScanner));
|
|
1518
|
+
}
|
|
1519
|
+
if (commentCodes.length === 0) return armScanner({ kind: "class", ranges });
|
|
1520
|
+
return fusedTriviaScanner(ranges, commentCodes);
|
|
1521
|
+
}
|
|
1411
1522
|
function blockCommentSource(source) {
|
|
1412
1523
|
return source === "\\/\\*(?:[^*]|\\*(?!\\/))*\\*\\/" || source === "\\/\\*[^]*?\\*\\/";
|
|
1413
1524
|
}
|
|
@@ -1724,6 +1835,7 @@ function markUnusedValues(root) {
|
|
|
1724
1835
|
}
|
|
1725
1836
|
|
|
1726
1837
|
// src/combinators/parser.ts
|
|
1838
|
+
var RULE_ORDER = "__parsemanRuleOrder";
|
|
1727
1839
|
function tagRule(r, key) {
|
|
1728
1840
|
;
|
|
1729
1841
|
r._ruleName = key;
|
|
@@ -1768,6 +1880,11 @@ function rules(a, b) {
|
|
|
1768
1880
|
for (const key of Object.keys(definitions)) {
|
|
1769
1881
|
markUnusedValues(cache[key]);
|
|
1770
1882
|
}
|
|
1883
|
+
Object.defineProperty(cache, RULE_ORDER, {
|
|
1884
|
+
value: Object.keys(definitions),
|
|
1885
|
+
enumerable: false,
|
|
1886
|
+
configurable: true
|
|
1887
|
+
});
|
|
1771
1888
|
return cache;
|
|
1772
1889
|
}
|
|
1773
1890
|
|