parseman 0.26.0 → 0.26.2
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/choice.d.ts.map +1 -1
- package/dist/compiler/codegen.d.ts.map +1 -1
- package/dist/compiler/ir-serialize.d.ts.map +1 -1
- package/dist/index.cjs +227 -170
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +227 -170
- package/dist/index.js.map +4 -4
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.cjs +266 -167
- package/dist/plugin/index.cjs.map +4 -4
- package/dist/plugin/index.js +266 -167
- package/dist/plugin/index.js.map +4 -4
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evaluator.d.ts","sourceRoot":"","sources":["../../src/plugin/evaluator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EACV,UAAU,EAAE,IAAI,EAMjB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"evaluator.d.ts","sourceRoot":"","sources":["../../src/plugin/evaluator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EACV,UAAU,EAAE,IAAI,EAMjB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AA2E7C,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,CAAA;IAC1B,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB,CAAA;AACD,MAAM,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;AAM3C,KAAK,gBAAgB,GAAG;IAAE,GAAG,EAAE,aAAa,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAA;AA4dhE,0EAA0E;AAC1E,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,KAAK,EACZ,IAAI,CAAC,EAAE,MAAM,GACZ,gBAAgB,GAAG,IAAI,CAUzB;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAC1B,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,KAAK,EACZ,IAAI,CAAC,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,EAAE,GACtB,UAAU,CAAC,OAAO,CAAC,GAAG,IAAI,CAE5B;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,KAAK,EACZ,IAAI,CAAC,EAAE,MAAM,GACZ,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI,CAM9B;AAiED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,UAAU,EACvB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EAAE,GACrB,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAqGzC;AAED,oEAAoE;AACpE,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG;IAAE,MAAM,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,IAAI,CAAA;CAAE,CAAA;AAQlF;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,KAAK,GACX,YAAY,GAAG,IAAI,CAQrB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,UAAU,EACpB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,MAAM,GACX,OAAO,CAoBT;AAED,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAcnF"}
|
package/dist/plugin/index.cjs
CHANGED
|
@@ -912,12 +912,159 @@ function keywords(words, opts = {}) {
|
|
|
912
912
|
};
|
|
913
913
|
}
|
|
914
914
|
|
|
915
|
+
// src/recovery/scan.ts
|
|
916
|
+
function probeAt(sentinel, input, pos, ctx) {
|
|
917
|
+
const s = {
|
|
918
|
+
_probe: ctx._probe,
|
|
919
|
+
_errors: ctx._errors,
|
|
920
|
+
_cstLeaves: ctx._cstLeaves,
|
|
921
|
+
_cstChildren: ctx._cstChildren,
|
|
922
|
+
_cstRawChildren: ctx._cstRawChildren,
|
|
923
|
+
_cstTriviaLog: ctx._cstTriviaLog,
|
|
924
|
+
_triviaLog: ctx._triviaLog,
|
|
925
|
+
_fields: ctx._fields,
|
|
926
|
+
_cstBuf: ctx._cstBuf,
|
|
927
|
+
_tolerant: ctx._tolerant,
|
|
928
|
+
_sync: ctx._sync
|
|
929
|
+
};
|
|
930
|
+
ctx._probe = void 0;
|
|
931
|
+
ctx._errors = void 0;
|
|
932
|
+
ctx._cstLeaves = void 0;
|
|
933
|
+
ctx._cstChildren = void 0;
|
|
934
|
+
ctx._cstRawChildren = void 0;
|
|
935
|
+
ctx._cstTriviaLog = void 0;
|
|
936
|
+
ctx._triviaLog = void 0;
|
|
937
|
+
ctx._fields = void 0;
|
|
938
|
+
ctx._cstBuf = void 0;
|
|
939
|
+
ctx._tolerant = void 0;
|
|
940
|
+
ctx._sync = void 0;
|
|
941
|
+
try {
|
|
942
|
+
return sentinel.parse(input, pos, ctx).ok;
|
|
943
|
+
} finally {
|
|
944
|
+
ctx._probe = s._probe;
|
|
945
|
+
ctx._errors = s._errors;
|
|
946
|
+
ctx._cstLeaves = s._cstLeaves;
|
|
947
|
+
ctx._cstChildren = s._cstChildren;
|
|
948
|
+
ctx._cstRawChildren = s._cstRawChildren;
|
|
949
|
+
ctx._cstTriviaLog = s._cstTriviaLog;
|
|
950
|
+
ctx._triviaLog = s._triviaLog;
|
|
951
|
+
ctx._fields = s._fields;
|
|
952
|
+
ctx._cstBuf = s._cstBuf;
|
|
953
|
+
ctx._tolerant = s._tolerant;
|
|
954
|
+
ctx._sync = s._sync;
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
function orSentinel(a, b) {
|
|
958
|
+
if (b === void 0) return a;
|
|
959
|
+
return {
|
|
960
|
+
_tag: "orSentinel",
|
|
961
|
+
_meta: { firstSet: { kind: "any" }, canMatchNewline: false, isTrivia: false },
|
|
962
|
+
_def: { tag: "unknown" },
|
|
963
|
+
parse(input, pos, ctx) {
|
|
964
|
+
const ra = a.parse(input, pos, ctx);
|
|
965
|
+
if (ra.ok) return ra;
|
|
966
|
+
return b.parse(input, pos, ctx);
|
|
967
|
+
}
|
|
968
|
+
};
|
|
969
|
+
}
|
|
970
|
+
function firstSetSentinel(fs2) {
|
|
971
|
+
if (fs2.kind !== "ranges" || fs2.ranges.length === 0) return null;
|
|
972
|
+
const ranges = fs2.ranges;
|
|
973
|
+
return {
|
|
974
|
+
_tag: "firstSetSentinel",
|
|
975
|
+
_meta: { firstSet: fs2, canMatchNewline: false, isTrivia: false },
|
|
976
|
+
_def: { tag: "unknown" },
|
|
977
|
+
parse(input, pos) {
|
|
978
|
+
const code = pos < input.length ? input.codePointAt(pos) : void 0;
|
|
979
|
+
if (code !== void 0) {
|
|
980
|
+
for (const r of ranges) {
|
|
981
|
+
if (code >= r.lo && code <= r.hi) return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
return { ok: false, expected: [], span: { start: pos, end: pos } };
|
|
985
|
+
}
|
|
986
|
+
};
|
|
987
|
+
}
|
|
988
|
+
function recoverScan(input, from, ctx, sync, expected) {
|
|
989
|
+
let scanPos = from;
|
|
990
|
+
while (scanPos < input.length && !probeAt(sync, input, scanPos, ctx)) scanPos++;
|
|
991
|
+
const error = { _tag: "parseError", span: { start: from, end: scanPos }, expected };
|
|
992
|
+
ctx._errors?.push(error);
|
|
993
|
+
return { error, end: scanPos };
|
|
994
|
+
}
|
|
995
|
+
function matchesAt(sentinel, input, pos, ctx) {
|
|
996
|
+
return probeAt(sentinel, input, pos, ctx);
|
|
997
|
+
}
|
|
998
|
+
function captureError(ctx, error) {
|
|
999
|
+
if (cstCaptureActive(ctx)) pushCstChild(ctx, error, error);
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
// src/combinators/expect.ts
|
|
1003
|
+
function deriveExpected(c) {
|
|
1004
|
+
const def = c._def;
|
|
1005
|
+
switch (def.tag) {
|
|
1006
|
+
case "literal":
|
|
1007
|
+
return [JSON.stringify(def.value)];
|
|
1008
|
+
case "regex":
|
|
1009
|
+
return [`/${def.source}/`];
|
|
1010
|
+
case "keywords":
|
|
1011
|
+
return def.words.map((w) => JSON.stringify(w));
|
|
1012
|
+
case "label":
|
|
1013
|
+
return [def.label];
|
|
1014
|
+
case "choice":
|
|
1015
|
+
return def.parsers.flatMap(deriveExpected);
|
|
1016
|
+
case "sequence":
|
|
1017
|
+
return def.parsers.length > 0 ? deriveExpected(def.parsers[0]) : [];
|
|
1018
|
+
case "node":
|
|
1019
|
+
case "grammar":
|
|
1020
|
+
case "trivia":
|
|
1021
|
+
case "token":
|
|
1022
|
+
case "optional":
|
|
1023
|
+
case "many":
|
|
1024
|
+
case "oneOrMore":
|
|
1025
|
+
case "transform":
|
|
1026
|
+
case "not":
|
|
1027
|
+
return deriveExpected(def.parser);
|
|
1028
|
+
case "lazy": {
|
|
1029
|
+
const name = c._ruleName;
|
|
1030
|
+
try {
|
|
1031
|
+
return deriveExpected(def.thunk());
|
|
1032
|
+
} catch {
|
|
1033
|
+
return name ? [name] : [];
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
default:
|
|
1037
|
+
return [];
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
function expect(combinator, label2) {
|
|
1041
|
+
const expected = label2 !== void 0 ? [label2] : deriveExpected(combinator);
|
|
1042
|
+
const meta = {
|
|
1043
|
+
firstSet: combinator._meta.firstSet,
|
|
1044
|
+
canMatchNewline: combinator._meta.canMatchNewline,
|
|
1045
|
+
isTrivia: false
|
|
1046
|
+
};
|
|
1047
|
+
return {
|
|
1048
|
+
_tag: "expect",
|
|
1049
|
+
_meta: meta,
|
|
1050
|
+
_def: { tag: "expect", parser: combinator, label: label2, expected },
|
|
1051
|
+
parse(input, pos, ctx) {
|
|
1052
|
+
const result = combinator.parse(input, pos, ctx);
|
|
1053
|
+
if (result.ok) return result;
|
|
1054
|
+
const error = { _tag: "parseError", span: { start: pos, end: pos }, expected };
|
|
1055
|
+
ctx._errors?.push(error);
|
|
1056
|
+
if (ctx._tolerant) captureError(ctx, error);
|
|
1057
|
+
return { ok: true, value: error, span: { start: pos, end: pos } };
|
|
1058
|
+
}
|
|
1059
|
+
};
|
|
1060
|
+
}
|
|
1061
|
+
|
|
915
1062
|
// src/combinators/choice.ts
|
|
916
1063
|
function choice(...args) {
|
|
917
1064
|
const parsers = args.map((a) => "gate" in a ? a.combinator : a);
|
|
918
1065
|
const gates = args.map((a) => "gate" in a ? a.gate : null);
|
|
919
1066
|
const hasGates = gates.some((g) => g !== null);
|
|
920
|
-
const disjoint =
|
|
1067
|
+
const disjoint = areDisjoint(parsers.map((p) => p._meta.firstSet)) && parsers.every((p) => !matchesEmpty(p));
|
|
921
1068
|
let combined = { kind: "empty" };
|
|
922
1069
|
for (const p of parsers) combined = union(combined, p._meta.firstSet);
|
|
923
1070
|
const meta = {
|
|
@@ -956,17 +1103,21 @@ function choice(...args) {
|
|
|
956
1103
|
const expected = [];
|
|
957
1104
|
if (disjoint && pos < input.length) {
|
|
958
1105
|
const code = input.codePointAt(pos);
|
|
959
|
-
let
|
|
960
|
-
if (
|
|
961
|
-
for (
|
|
962
|
-
if (inFirstSet(code,
|
|
963
|
-
|
|
1106
|
+
let idx = code < 128 ? asciiDispatch[code] : -1;
|
|
1107
|
+
if (idx < 0) {
|
|
1108
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1109
|
+
if (inFirstSet(code, parsers[i]._meta.firstSet)) {
|
|
1110
|
+
idx = i;
|
|
964
1111
|
break;
|
|
965
1112
|
}
|
|
966
1113
|
}
|
|
967
1114
|
}
|
|
968
|
-
if (
|
|
969
|
-
const
|
|
1115
|
+
if (idx >= 0) {
|
|
1116
|
+
const gate = gates[idx];
|
|
1117
|
+
if (gate && !gate(ctx.state)) {
|
|
1118
|
+
return { ok: false, expected: deriveExpected(parsers[idx]), span: { start: pos, end: pos } };
|
|
1119
|
+
}
|
|
1120
|
+
const result = parsers[idx].parse(input, pos, ctx);
|
|
970
1121
|
if (result.ok) return result;
|
|
971
1122
|
expected.push(...result.expected);
|
|
972
1123
|
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
@@ -1147,13 +1298,13 @@ function areDisjoint(sets) {
|
|
|
1147
1298
|
return true;
|
|
1148
1299
|
}
|
|
1149
1300
|
function buildAsciiDispatch(parsers) {
|
|
1150
|
-
const table = Array(128).fill(
|
|
1151
|
-
for (
|
|
1152
|
-
const fs2 =
|
|
1301
|
+
const table = Array(128).fill(-1);
|
|
1302
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1303
|
+
const fs2 = parsers[i]._meta.firstSet;
|
|
1153
1304
|
if (fs2.kind !== "ranges") continue;
|
|
1154
1305
|
for (const { lo, hi } of fs2.ranges) {
|
|
1155
1306
|
for (let code = Math.max(0, lo); code <= Math.min(127, hi); code++) {
|
|
1156
|
-
table[code] =
|
|
1307
|
+
table[code] = i;
|
|
1157
1308
|
}
|
|
1158
1309
|
}
|
|
1159
1310
|
}
|
|
@@ -1535,93 +1686,6 @@ function scanBlockComment(input, cur) {
|
|
|
1535
1686
|
return close === -1 ? cur : close + 2;
|
|
1536
1687
|
}
|
|
1537
1688
|
|
|
1538
|
-
// src/recovery/scan.ts
|
|
1539
|
-
function probeAt(sentinel, input, pos, ctx) {
|
|
1540
|
-
const s = {
|
|
1541
|
-
_probe: ctx._probe,
|
|
1542
|
-
_errors: ctx._errors,
|
|
1543
|
-
_cstLeaves: ctx._cstLeaves,
|
|
1544
|
-
_cstChildren: ctx._cstChildren,
|
|
1545
|
-
_cstRawChildren: ctx._cstRawChildren,
|
|
1546
|
-
_cstTriviaLog: ctx._cstTriviaLog,
|
|
1547
|
-
_triviaLog: ctx._triviaLog,
|
|
1548
|
-
_fields: ctx._fields,
|
|
1549
|
-
_cstBuf: ctx._cstBuf,
|
|
1550
|
-
_tolerant: ctx._tolerant,
|
|
1551
|
-
_sync: ctx._sync
|
|
1552
|
-
};
|
|
1553
|
-
ctx._probe = void 0;
|
|
1554
|
-
ctx._errors = void 0;
|
|
1555
|
-
ctx._cstLeaves = void 0;
|
|
1556
|
-
ctx._cstChildren = void 0;
|
|
1557
|
-
ctx._cstRawChildren = void 0;
|
|
1558
|
-
ctx._cstTriviaLog = void 0;
|
|
1559
|
-
ctx._triviaLog = void 0;
|
|
1560
|
-
ctx._fields = void 0;
|
|
1561
|
-
ctx._cstBuf = void 0;
|
|
1562
|
-
ctx._tolerant = void 0;
|
|
1563
|
-
ctx._sync = void 0;
|
|
1564
|
-
try {
|
|
1565
|
-
return sentinel.parse(input, pos, ctx).ok;
|
|
1566
|
-
} finally {
|
|
1567
|
-
ctx._probe = s._probe;
|
|
1568
|
-
ctx._errors = s._errors;
|
|
1569
|
-
ctx._cstLeaves = s._cstLeaves;
|
|
1570
|
-
ctx._cstChildren = s._cstChildren;
|
|
1571
|
-
ctx._cstRawChildren = s._cstRawChildren;
|
|
1572
|
-
ctx._cstTriviaLog = s._cstTriviaLog;
|
|
1573
|
-
ctx._triviaLog = s._triviaLog;
|
|
1574
|
-
ctx._fields = s._fields;
|
|
1575
|
-
ctx._cstBuf = s._cstBuf;
|
|
1576
|
-
ctx._tolerant = s._tolerant;
|
|
1577
|
-
ctx._sync = s._sync;
|
|
1578
|
-
}
|
|
1579
|
-
}
|
|
1580
|
-
function orSentinel(a, b) {
|
|
1581
|
-
if (b === void 0) return a;
|
|
1582
|
-
return {
|
|
1583
|
-
_tag: "orSentinel",
|
|
1584
|
-
_meta: { firstSet: { kind: "any" }, canMatchNewline: false, isTrivia: false },
|
|
1585
|
-
_def: { tag: "unknown" },
|
|
1586
|
-
parse(input, pos, ctx) {
|
|
1587
|
-
const ra = a.parse(input, pos, ctx);
|
|
1588
|
-
if (ra.ok) return ra;
|
|
1589
|
-
return b.parse(input, pos, ctx);
|
|
1590
|
-
}
|
|
1591
|
-
};
|
|
1592
|
-
}
|
|
1593
|
-
function firstSetSentinel(fs2) {
|
|
1594
|
-
if (fs2.kind !== "ranges" || fs2.ranges.length === 0) return null;
|
|
1595
|
-
const ranges = fs2.ranges;
|
|
1596
|
-
return {
|
|
1597
|
-
_tag: "firstSetSentinel",
|
|
1598
|
-
_meta: { firstSet: fs2, canMatchNewline: false, isTrivia: false },
|
|
1599
|
-
_def: { tag: "unknown" },
|
|
1600
|
-
parse(input, pos) {
|
|
1601
|
-
const code = pos < input.length ? input.codePointAt(pos) : void 0;
|
|
1602
|
-
if (code !== void 0) {
|
|
1603
|
-
for (const r of ranges) {
|
|
1604
|
-
if (code >= r.lo && code <= r.hi) return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
1605
|
-
}
|
|
1606
|
-
}
|
|
1607
|
-
return { ok: false, expected: [], span: { start: pos, end: pos } };
|
|
1608
|
-
}
|
|
1609
|
-
};
|
|
1610
|
-
}
|
|
1611
|
-
function recoverScan(input, from, ctx, sync, expected) {
|
|
1612
|
-
let scanPos = from;
|
|
1613
|
-
while (scanPos < input.length && !probeAt(sync, input, scanPos, ctx)) scanPos++;
|
|
1614
|
-
const error = { _tag: "parseError", span: { start: from, end: scanPos }, expected };
|
|
1615
|
-
ctx._errors?.push(error);
|
|
1616
|
-
return { error, end: scanPos };
|
|
1617
|
-
}
|
|
1618
|
-
function matchesAt(sentinel, input, pos, ctx) {
|
|
1619
|
-
return probeAt(sentinel, input, pos, ctx);
|
|
1620
|
-
}
|
|
1621
|
-
function captureError(ctx, error) {
|
|
1622
|
-
if (cstCaptureActive(ctx)) pushCstChild(ctx, error, error);
|
|
1623
|
-
}
|
|
1624
|
-
|
|
1625
1689
|
// src/combinators/sequence.ts
|
|
1626
1690
|
function sequence(...parsers) {
|
|
1627
1691
|
const meta = {
|
|
@@ -1723,66 +1787,6 @@ function sequence(...parsers) {
|
|
|
1723
1787
|
};
|
|
1724
1788
|
}
|
|
1725
1789
|
|
|
1726
|
-
// src/combinators/expect.ts
|
|
1727
|
-
function deriveExpected(c) {
|
|
1728
|
-
const def = c._def;
|
|
1729
|
-
switch (def.tag) {
|
|
1730
|
-
case "literal":
|
|
1731
|
-
return [JSON.stringify(def.value)];
|
|
1732
|
-
case "regex":
|
|
1733
|
-
return [`/${def.source}/`];
|
|
1734
|
-
case "keywords":
|
|
1735
|
-
return def.words.map((w) => JSON.stringify(w));
|
|
1736
|
-
case "label":
|
|
1737
|
-
return [def.label];
|
|
1738
|
-
case "choice":
|
|
1739
|
-
return def.parsers.flatMap(deriveExpected);
|
|
1740
|
-
case "sequence":
|
|
1741
|
-
return def.parsers.length > 0 ? deriveExpected(def.parsers[0]) : [];
|
|
1742
|
-
case "node":
|
|
1743
|
-
case "grammar":
|
|
1744
|
-
case "trivia":
|
|
1745
|
-
case "token":
|
|
1746
|
-
case "optional":
|
|
1747
|
-
case "many":
|
|
1748
|
-
case "oneOrMore":
|
|
1749
|
-
case "transform":
|
|
1750
|
-
case "not":
|
|
1751
|
-
return deriveExpected(def.parser);
|
|
1752
|
-
case "lazy": {
|
|
1753
|
-
const name = c._ruleName;
|
|
1754
|
-
try {
|
|
1755
|
-
return deriveExpected(def.thunk());
|
|
1756
|
-
} catch {
|
|
1757
|
-
return name ? [name] : [];
|
|
1758
|
-
}
|
|
1759
|
-
}
|
|
1760
|
-
default:
|
|
1761
|
-
return [];
|
|
1762
|
-
}
|
|
1763
|
-
}
|
|
1764
|
-
function expect(combinator, label2) {
|
|
1765
|
-
const expected = label2 !== void 0 ? [label2] : deriveExpected(combinator);
|
|
1766
|
-
const meta = {
|
|
1767
|
-
firstSet: combinator._meta.firstSet,
|
|
1768
|
-
canMatchNewline: combinator._meta.canMatchNewline,
|
|
1769
|
-
isTrivia: false
|
|
1770
|
-
};
|
|
1771
|
-
return {
|
|
1772
|
-
_tag: "expect",
|
|
1773
|
-
_meta: meta,
|
|
1774
|
-
_def: { tag: "expect", parser: combinator, label: label2, expected },
|
|
1775
|
-
parse(input, pos, ctx) {
|
|
1776
|
-
const result = combinator.parse(input, pos, ctx);
|
|
1777
|
-
if (result.ok) return result;
|
|
1778
|
-
const error = { _tag: "parseError", span: { start: pos, end: pos }, expected };
|
|
1779
|
-
ctx._errors?.push(error);
|
|
1780
|
-
if (ctx._tolerant) captureError(ctx, error);
|
|
1781
|
-
return { ok: true, value: error, span: { start: pos, end: pos } };
|
|
1782
|
-
}
|
|
1783
|
-
};
|
|
1784
|
-
}
|
|
1785
|
-
|
|
1786
1790
|
// src/combinators/repeat.ts
|
|
1787
1791
|
function repItem(combinator, input, cur, ctx) {
|
|
1788
1792
|
const mark = saveTriviaMark(ctx);
|
|
@@ -4559,6 +4563,21 @@ function emitDisjointArm(p, ctx, pos, valV, endV) {
|
|
|
4559
4563
|
`${ind(ctx)}${endV} = ${endVar}`
|
|
4560
4564
|
];
|
|
4561
4565
|
}
|
|
4566
|
+
function emitDisjointArmGated(def, i, ctx, pos, valV, endV) {
|
|
4567
|
+
const p = def.parsers[i];
|
|
4568
|
+
const gate = def.gates[i];
|
|
4569
|
+
if (!gate) return emitDisjointArm(p, ctx, pos, valV, endV);
|
|
4570
|
+
const gateIdx = ctx.mapFns.length;
|
|
4571
|
+
ctx.mapFns.push(gate);
|
|
4572
|
+
ctx.mapFnSrcs.push(def.gateSrcs?.[i] ?? null);
|
|
4573
|
+
const gateCond = `${mfRef(ctx)}[${gateIdx}](_ctx.state)`;
|
|
4574
|
+
const stmts = [`${ind(ctx)}if (${gateCond}) {`];
|
|
4575
|
+
ctx.indent++;
|
|
4576
|
+
stmts.push(...emitDisjointArm(p, ctx, pos, valV, endV));
|
|
4577
|
+
ctx.indent--;
|
|
4578
|
+
stmts.push(`${ind(ctx)}} else { ${failArrBody(ctx, deriveExpectedArr([p]), pos)} }`);
|
|
4579
|
+
return stmts;
|
|
4580
|
+
}
|
|
4562
4581
|
function emitChoice(def, ctx, pos) {
|
|
4563
4582
|
const allExpected = deriveExpectedArr(def.parsers);
|
|
4564
4583
|
if (def.disjoint) {
|
|
@@ -4574,12 +4593,11 @@ function emitChoice(def, ctx, pos) {
|
|
|
4574
4593
|
stmts.push(`${ind(ctx)}switch (${codeV}) {`);
|
|
4575
4594
|
ctx.indent++;
|
|
4576
4595
|
for (let i = 0; i < def.parsers.length; i++) {
|
|
4577
|
-
const p = def.parsers[i];
|
|
4578
4596
|
for (const cp of plan.cases[i]) stmts.push(`${ind(ctx)}case ${cp}:`);
|
|
4579
4597
|
stmts.push(`${ind(ctx)}{`);
|
|
4580
4598
|
ctx.indent++;
|
|
4581
4599
|
stmts.push(
|
|
4582
|
-
...
|
|
4600
|
+
...emitDisjointArmGated(def, i, ctx, pos, valV, endV),
|
|
4583
4601
|
`${ind(ctx)}break`
|
|
4584
4602
|
);
|
|
4585
4603
|
ctx.indent--;
|
|
@@ -4591,13 +4609,14 @@ function emitChoice(def, ctx, pos) {
|
|
|
4591
4609
|
return { stmts, valueVar: valV, endVar: endV };
|
|
4592
4610
|
}
|
|
4593
4611
|
let first = true;
|
|
4594
|
-
for (
|
|
4612
|
+
for (let i = 0; i < def.parsers.length; i++) {
|
|
4613
|
+
const p = def.parsers[i];
|
|
4595
4614
|
const cond = firstSetCond(codeV, p._meta.firstSet);
|
|
4596
4615
|
const kw = first ? "if" : "else if";
|
|
4597
4616
|
first = false;
|
|
4598
4617
|
stmts.push(`${ind(ctx)}${kw} (${cond}) {`);
|
|
4599
4618
|
ctx.indent++;
|
|
4600
|
-
stmts.push(...
|
|
4619
|
+
stmts.push(...emitDisjointArmGated(def, i, ctx, pos, valV, endV));
|
|
4601
4620
|
ctx.indent--;
|
|
4602
4621
|
stmts.push(`${ind(ctx)}}`);
|
|
4603
4622
|
}
|
|
@@ -6341,6 +6360,34 @@ function evalRuleMapIR(ir) {
|
|
|
6341
6360
|
n._def.buildSrc = src;
|
|
6342
6361
|
return n;
|
|
6343
6362
|
};
|
|
6363
|
+
const _gch = (items) => {
|
|
6364
|
+
const gateSrcs = [];
|
|
6365
|
+
const arms = items.map((it) => {
|
|
6366
|
+
if (Array.isArray(it)) {
|
|
6367
|
+
const [src, comb] = it;
|
|
6368
|
+
gateSrcs.push(src);
|
|
6369
|
+
let gate;
|
|
6370
|
+
try {
|
|
6371
|
+
gate = (0, eval)(`(${src})`);
|
|
6372
|
+
} catch {
|
|
6373
|
+
gate = () => {
|
|
6374
|
+
throw new Error("IR gate fn not materialized");
|
|
6375
|
+
};
|
|
6376
|
+
}
|
|
6377
|
+
return { gate, combinator: comb };
|
|
6378
|
+
}
|
|
6379
|
+
gateSrcs.push(null);
|
|
6380
|
+
return it;
|
|
6381
|
+
});
|
|
6382
|
+
const c = choice(...arms);
|
|
6383
|
+
const gates = c._def.gates;
|
|
6384
|
+
if (gates && gates.length !== gateSrcs.length) {
|
|
6385
|
+
throw new Error(`_gch: gateSrcs length ${gateSrcs.length} != choice gates length ${gates.length}`);
|
|
6386
|
+
}
|
|
6387
|
+
;
|
|
6388
|
+
c._def.gateSrcs = gateSrcs;
|
|
6389
|
+
return c;
|
|
6390
|
+
};
|
|
6344
6391
|
const fn = new Function(
|
|
6345
6392
|
"rules",
|
|
6346
6393
|
"ref",
|
|
@@ -6366,6 +6413,7 @@ function evalRuleMapIR(ir) {
|
|
|
6366
6413
|
"expect",
|
|
6367
6414
|
"_tf",
|
|
6368
6415
|
"_nd",
|
|
6416
|
+
"_gch",
|
|
6369
6417
|
`return (${ir})`
|
|
6370
6418
|
);
|
|
6371
6419
|
const map = fn(
|
|
@@ -6392,7 +6440,8 @@ function evalRuleMapIR(ir) {
|
|
|
6392
6440
|
field,
|
|
6393
6441
|
expect,
|
|
6394
6442
|
_tf,
|
|
6395
|
-
_nd
|
|
6443
|
+
_nd,
|
|
6444
|
+
_gch
|
|
6396
6445
|
);
|
|
6397
6446
|
return Object.entries(map);
|
|
6398
6447
|
}
|
|
@@ -6504,8 +6553,16 @@ ${body}
|
|
|
6504
6553
|
case "sequence":
|
|
6505
6554
|
return `sequence(${def.parsers.map(kid).join(", ")})`;
|
|
6506
6555
|
case "choice": {
|
|
6507
|
-
|
|
6508
|
-
return `choice(${def.parsers.map(kid).join(", ")})`;
|
|
6556
|
+
const gates = def.gates;
|
|
6557
|
+
if (gates.every((g) => g === null)) return `choice(${def.parsers.map(kid).join(", ")})`;
|
|
6558
|
+
const gateSrcs = def.gateSrcs;
|
|
6559
|
+
const items = def.parsers.map((p, i) => {
|
|
6560
|
+
if (gates[i] === null) return kid(p);
|
|
6561
|
+
const src = gateSrcs?.[i];
|
|
6562
|
+
if (src == null) throw new Unserializable("choice gate() has no captured source");
|
|
6563
|
+
return `[${JSON.stringify(src)}, ${kid(p)}]`;
|
|
6564
|
+
});
|
|
6565
|
+
return `_gch([${items.join(", ")}])`;
|
|
6509
6566
|
}
|
|
6510
6567
|
case "many":
|
|
6511
6568
|
return `many(${kid(def.parser)})`;
|
|
@@ -6686,6 +6743,48 @@ var { isFinite } = Number;
|
|
|
6686
6743
|
registerRegexAnalyzer(firstSetFromRegex);
|
|
6687
6744
|
|
|
6688
6745
|
// src/plugin/evaluator.ts
|
|
6746
|
+
function stripTsFromSource(node2, code) {
|
|
6747
|
+
const cuts = [];
|
|
6748
|
+
const walk2 = (n) => {
|
|
6749
|
+
if (!n || typeof n !== "object") return;
|
|
6750
|
+
const rec = n;
|
|
6751
|
+
if (typeof rec.type === "string" && rec.type.startsWith("TS") && typeof rec.start === "number" && typeof rec.end === "number") {
|
|
6752
|
+
const ex = rec.expression;
|
|
6753
|
+
if ((rec.type === "TSAsExpression" || rec.type === "TSSatisfiesExpression" || rec.type === "TSNonNullExpression" || rec.type === "TSInstantiationExpression") && ex && typeof ex.end === "number") {
|
|
6754
|
+
cuts.push([ex.end, rec.end]);
|
|
6755
|
+
walk2(rec.expression);
|
|
6756
|
+
return;
|
|
6757
|
+
}
|
|
6758
|
+
if (rec.type === "TSTypeAssertion" && ex && typeof ex.start === "number") {
|
|
6759
|
+
cuts.push([rec.start, ex.start]);
|
|
6760
|
+
walk2(rec.expression);
|
|
6761
|
+
return;
|
|
6762
|
+
}
|
|
6763
|
+
cuts.push([rec.start, rec.end]);
|
|
6764
|
+
return;
|
|
6765
|
+
}
|
|
6766
|
+
for (const key of Object.keys(rec)) {
|
|
6767
|
+
if (key === "type" || key === "start" || key === "end") continue;
|
|
6768
|
+
const v2 = rec[key];
|
|
6769
|
+
if (Array.isArray(v2)) {
|
|
6770
|
+
for (const item of v2) walk2(item);
|
|
6771
|
+
} else if (v2 && typeof v2 === "object") walk2(v2);
|
|
6772
|
+
}
|
|
6773
|
+
};
|
|
6774
|
+
walk2(node2);
|
|
6775
|
+
const start = node2.start;
|
|
6776
|
+
const end = node2.end;
|
|
6777
|
+
if (cuts.length === 0) return code.slice(start, end);
|
|
6778
|
+
cuts.sort((a, b) => a[0] - b[0]);
|
|
6779
|
+
let out = "";
|
|
6780
|
+
let cur = start;
|
|
6781
|
+
for (const [s, e] of cuts) {
|
|
6782
|
+
if (s < cur) continue;
|
|
6783
|
+
out += code.slice(cur, s);
|
|
6784
|
+
cur = e;
|
|
6785
|
+
}
|
|
6786
|
+
return out + code.slice(cur, end);
|
|
6787
|
+
}
|
|
6689
6788
|
function isWordFactory(v2) {
|
|
6690
6789
|
return !!v2 && typeof v2 === "object" && v2.tag === "wordFactory";
|
|
6691
6790
|
}
|
|
@@ -6961,7 +7060,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
6961
7060
|
if (isGatedArmExpr(argNode)) {
|
|
6962
7061
|
const parts = gatedArmParts(argNode);
|
|
6963
7062
|
if (!parts) return null;
|
|
6964
|
-
const gateSrc =
|
|
7063
|
+
const gateSrc = stripTsFromSource(parts.gate, code);
|
|
6965
7064
|
mfs.push(gateSrc);
|
|
6966
7065
|
const combi = anyValue(parts.combinator, scope, code, mfs);
|
|
6967
7066
|
if (!isCombinator(combi)) return null;
|