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":"choice.d.ts","sourceRoot":"","sources":["../../src/combinators/choice.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EAC+B,QAAQ,EAClD,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"choice.d.ts","sourceRoot":"","sources":["../../src/combinators/choice.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EAC+B,QAAQ,EAClD,MAAM,aAAa,CAAA;AAKpB,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,KAAK,CAAA;AACvH,KAAK,SAAS,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI;KACrE,CAAC,IAAI,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAChC,CAAC,MAAM,CAAC,SAAS,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;AAEjD,wBAAgB,MAAM,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EACxH,GAAG,IAAI,EAAE,CAAC,GACT,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAwJ1B;AAwFD,uEAAuE;AACvE,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,MAAM,GAAG,IAAI,CAKzE;AAED,qEAAqE;AACrE,wBAAgB,eAAe,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAMhG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../../src/compiler/codegen.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,UAAU,EAAa,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAA4B,MAAM,aAAa,CAAA;AA0BnI;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,uTAC0R,CAAA;AActT,8EAA8E;AAC9E,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C;AAED,+EAA+E;AAC/E,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CAI7C;AAudD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,GAAG,MAAM,CAQlE;AAcD,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CAA0B;
|
|
1
|
+
{"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../../src/compiler/codegen.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ir-serialize.d.ts","sourceRoot":"","sources":["../../src/compiler/ir-serialize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,aAAa,CAAA;AAiBxD,KAAK,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,CAAA;AA4C/B,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,GAC9C,MAAM,GAAG,IAAI,CAUf;AAED;;oFAEoF;AACpF,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"ir-serialize.d.ts","sourceRoot":"","sources":["../../src/compiler/ir-serialize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,aAAa,CAAA;AAiBxD,KAAK,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,CAAA;AA4C/B,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,GAC9C,MAAM,GAAG,IAAI,CAUf;AAED;;oFAEoF;AACpF,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAgE/D"}
|
package/dist/index.cjs
CHANGED
|
@@ -924,12 +924,163 @@ function keywords(words, opts = {}) {
|
|
|
924
924
|
};
|
|
925
925
|
}
|
|
926
926
|
|
|
927
|
+
// src/recovery/scan.ts
|
|
928
|
+
function probeAt(sentinel, input, pos, ctx) {
|
|
929
|
+
const s = {
|
|
930
|
+
_probe: ctx._probe,
|
|
931
|
+
_errors: ctx._errors,
|
|
932
|
+
_cstLeaves: ctx._cstLeaves,
|
|
933
|
+
_cstChildren: ctx._cstChildren,
|
|
934
|
+
_cstRawChildren: ctx._cstRawChildren,
|
|
935
|
+
_cstTriviaLog: ctx._cstTriviaLog,
|
|
936
|
+
_triviaLog: ctx._triviaLog,
|
|
937
|
+
_fields: ctx._fields,
|
|
938
|
+
_cstBuf: ctx._cstBuf,
|
|
939
|
+
_tolerant: ctx._tolerant,
|
|
940
|
+
_sync: ctx._sync
|
|
941
|
+
};
|
|
942
|
+
ctx._probe = void 0;
|
|
943
|
+
ctx._errors = void 0;
|
|
944
|
+
ctx._cstLeaves = void 0;
|
|
945
|
+
ctx._cstChildren = void 0;
|
|
946
|
+
ctx._cstRawChildren = void 0;
|
|
947
|
+
ctx._cstTriviaLog = void 0;
|
|
948
|
+
ctx._triviaLog = void 0;
|
|
949
|
+
ctx._fields = void 0;
|
|
950
|
+
ctx._cstBuf = void 0;
|
|
951
|
+
ctx._tolerant = void 0;
|
|
952
|
+
ctx._sync = void 0;
|
|
953
|
+
try {
|
|
954
|
+
return sentinel.parse(input, pos, ctx).ok;
|
|
955
|
+
} finally {
|
|
956
|
+
ctx._probe = s._probe;
|
|
957
|
+
ctx._errors = s._errors;
|
|
958
|
+
ctx._cstLeaves = s._cstLeaves;
|
|
959
|
+
ctx._cstChildren = s._cstChildren;
|
|
960
|
+
ctx._cstRawChildren = s._cstRawChildren;
|
|
961
|
+
ctx._cstTriviaLog = s._cstTriviaLog;
|
|
962
|
+
ctx._triviaLog = s._triviaLog;
|
|
963
|
+
ctx._fields = s._fields;
|
|
964
|
+
ctx._cstBuf = s._cstBuf;
|
|
965
|
+
ctx._tolerant = s._tolerant;
|
|
966
|
+
ctx._sync = s._sync;
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
function orSentinel(a, b) {
|
|
970
|
+
if (b === void 0) return a;
|
|
971
|
+
return {
|
|
972
|
+
_tag: "orSentinel",
|
|
973
|
+
_meta: { firstSet: { kind: "any" }, canMatchNewline: false, isTrivia: false },
|
|
974
|
+
_def: { tag: "unknown" },
|
|
975
|
+
parse(input, pos, ctx) {
|
|
976
|
+
const ra = a.parse(input, pos, ctx);
|
|
977
|
+
if (ra.ok) return ra;
|
|
978
|
+
return b.parse(input, pos, ctx);
|
|
979
|
+
}
|
|
980
|
+
};
|
|
981
|
+
}
|
|
982
|
+
function firstSetSentinel(fs) {
|
|
983
|
+
if (fs.kind !== "ranges" || fs.ranges.length === 0) return null;
|
|
984
|
+
const ranges = fs.ranges;
|
|
985
|
+
return {
|
|
986
|
+
_tag: "firstSetSentinel",
|
|
987
|
+
_meta: { firstSet: fs, canMatchNewline: false, isTrivia: false },
|
|
988
|
+
_def: { tag: "unknown" },
|
|
989
|
+
parse(input, pos) {
|
|
990
|
+
const code = pos < input.length ? input.codePointAt(pos) : void 0;
|
|
991
|
+
if (code !== void 0) {
|
|
992
|
+
for (const r of ranges) {
|
|
993
|
+
if (code >= r.lo && code <= r.hi) return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
return { ok: false, expected: [], span: { start: pos, end: pos } };
|
|
997
|
+
}
|
|
998
|
+
};
|
|
999
|
+
}
|
|
1000
|
+
function recoverScan(input, from, ctx, sync, expected) {
|
|
1001
|
+
let scanPos = from;
|
|
1002
|
+
while (scanPos < input.length && !probeAt(sync, input, scanPos, ctx)) scanPos++;
|
|
1003
|
+
const error = { _tag: "parseError", span: { start: from, end: scanPos }, expected };
|
|
1004
|
+
ctx._errors?.push(error);
|
|
1005
|
+
return { error, end: scanPos };
|
|
1006
|
+
}
|
|
1007
|
+
function matchesAt(sentinel, input, pos, ctx) {
|
|
1008
|
+
return probeAt(sentinel, input, pos, ctx);
|
|
1009
|
+
}
|
|
1010
|
+
function captureError(ctx, error) {
|
|
1011
|
+
if (cstCaptureActive(ctx)) pushCstChild(ctx, error, error);
|
|
1012
|
+
}
|
|
1013
|
+
var REC = { scan: recoverScan, at: matchesAt, or: orSentinel, sentinel: firstSetSentinel, capture: captureError };
|
|
1014
|
+
|
|
1015
|
+
// src/combinators/expect.ts
|
|
1016
|
+
function deriveExpected(c) {
|
|
1017
|
+
const def = c._def;
|
|
1018
|
+
switch (def.tag) {
|
|
1019
|
+
case "literal":
|
|
1020
|
+
return [JSON.stringify(def.value)];
|
|
1021
|
+
case "regex":
|
|
1022
|
+
return [`/${def.source}/`];
|
|
1023
|
+
case "keywords":
|
|
1024
|
+
return def.words.map((w) => JSON.stringify(w));
|
|
1025
|
+
case "label":
|
|
1026
|
+
return [def.label];
|
|
1027
|
+
case "choice":
|
|
1028
|
+
return def.parsers.flatMap(deriveExpected);
|
|
1029
|
+
case "sequence":
|
|
1030
|
+
return def.parsers.length > 0 ? deriveExpected(def.parsers[0]) : [];
|
|
1031
|
+
case "node":
|
|
1032
|
+
case "grammar":
|
|
1033
|
+
case "trivia":
|
|
1034
|
+
case "token":
|
|
1035
|
+
case "optional":
|
|
1036
|
+
case "many":
|
|
1037
|
+
case "oneOrMore":
|
|
1038
|
+
case "transform":
|
|
1039
|
+
case "not":
|
|
1040
|
+
return deriveExpected(def.parser);
|
|
1041
|
+
case "lazy": {
|
|
1042
|
+
const name = c._ruleName;
|
|
1043
|
+
try {
|
|
1044
|
+
return deriveExpected(def.thunk());
|
|
1045
|
+
} catch {
|
|
1046
|
+
return name ? [name] : [];
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
default:
|
|
1050
|
+
return [];
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
function expect(combinator, label2) {
|
|
1054
|
+
const expected = label2 !== void 0 ? [label2] : deriveExpected(combinator);
|
|
1055
|
+
const meta = {
|
|
1056
|
+
firstSet: combinator._meta.firstSet,
|
|
1057
|
+
canMatchNewline: combinator._meta.canMatchNewline,
|
|
1058
|
+
isTrivia: false
|
|
1059
|
+
};
|
|
1060
|
+
return {
|
|
1061
|
+
_tag: "expect",
|
|
1062
|
+
_meta: meta,
|
|
1063
|
+
_def: { tag: "expect", parser: combinator, label: label2, expected },
|
|
1064
|
+
parse(input, pos, ctx) {
|
|
1065
|
+
const result = combinator.parse(input, pos, ctx);
|
|
1066
|
+
if (result.ok) return result;
|
|
1067
|
+
const error = { _tag: "parseError", span: { start: pos, end: pos }, expected };
|
|
1068
|
+
ctx._errors?.push(error);
|
|
1069
|
+
if (ctx._tolerant) captureError(ctx, error);
|
|
1070
|
+
return { ok: true, value: error, span: { start: pos, end: pos } };
|
|
1071
|
+
}
|
|
1072
|
+
};
|
|
1073
|
+
}
|
|
1074
|
+
function isParseError(value) {
|
|
1075
|
+
return typeof value === "object" && value !== null && value._tag === "parseError";
|
|
1076
|
+
}
|
|
1077
|
+
|
|
927
1078
|
// src/combinators/choice.ts
|
|
928
1079
|
function choice(...args) {
|
|
929
1080
|
const parsers = args.map((a) => "gate" in a ? a.combinator : a);
|
|
930
1081
|
const gates = args.map((a) => "gate" in a ? a.gate : null);
|
|
931
1082
|
const hasGates = gates.some((g) => g !== null);
|
|
932
|
-
const disjoint =
|
|
1083
|
+
const disjoint = areDisjoint(parsers.map((p) => p._meta.firstSet)) && parsers.every((p) => !matchesEmpty(p));
|
|
933
1084
|
let combined = { kind: "empty" };
|
|
934
1085
|
for (const p of parsers) combined = union(combined, p._meta.firstSet);
|
|
935
1086
|
const meta = {
|
|
@@ -968,17 +1119,21 @@ function choice(...args) {
|
|
|
968
1119
|
const expected = [];
|
|
969
1120
|
if (disjoint && pos < input.length) {
|
|
970
1121
|
const code = input.codePointAt(pos);
|
|
971
|
-
let
|
|
972
|
-
if (
|
|
973
|
-
for (
|
|
974
|
-
if (inFirstSet(code,
|
|
975
|
-
|
|
1122
|
+
let idx = code < 128 ? asciiDispatch[code] : -1;
|
|
1123
|
+
if (idx < 0) {
|
|
1124
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1125
|
+
if (inFirstSet(code, parsers[i]._meta.firstSet)) {
|
|
1126
|
+
idx = i;
|
|
976
1127
|
break;
|
|
977
1128
|
}
|
|
978
1129
|
}
|
|
979
1130
|
}
|
|
980
|
-
if (
|
|
981
|
-
const
|
|
1131
|
+
if (idx >= 0) {
|
|
1132
|
+
const gate = gates[idx];
|
|
1133
|
+
if (gate && !gate(ctx.state)) {
|
|
1134
|
+
return { ok: false, expected: deriveExpected(parsers[idx]), span: { start: pos, end: pos } };
|
|
1135
|
+
}
|
|
1136
|
+
const result = parsers[idx].parse(input, pos, ctx);
|
|
982
1137
|
if (result.ok) return result;
|
|
983
1138
|
expected.push(...result.expected);
|
|
984
1139
|
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
@@ -1159,13 +1314,13 @@ function areDisjoint(sets) {
|
|
|
1159
1314
|
return true;
|
|
1160
1315
|
}
|
|
1161
1316
|
function buildAsciiDispatch(parsers) {
|
|
1162
|
-
const table = Array(128).fill(
|
|
1163
|
-
for (
|
|
1164
|
-
const fs =
|
|
1317
|
+
const table = Array(128).fill(-1);
|
|
1318
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1319
|
+
const fs = parsers[i]._meta.firstSet;
|
|
1165
1320
|
if (fs.kind !== "ranges") continue;
|
|
1166
1321
|
for (const { lo, hi } of fs.ranges) {
|
|
1167
1322
|
for (let code = Math.max(0, lo); code <= Math.min(127, hi); code++) {
|
|
1168
|
-
table[code] =
|
|
1323
|
+
table[code] = i;
|
|
1169
1324
|
}
|
|
1170
1325
|
}
|
|
1171
1326
|
}
|
|
@@ -1547,94 +1702,6 @@ function scanBlockComment(input, cur) {
|
|
|
1547
1702
|
return close === -1 ? cur : close + 2;
|
|
1548
1703
|
}
|
|
1549
1704
|
|
|
1550
|
-
// src/recovery/scan.ts
|
|
1551
|
-
function probeAt(sentinel, input, pos, ctx) {
|
|
1552
|
-
const s = {
|
|
1553
|
-
_probe: ctx._probe,
|
|
1554
|
-
_errors: ctx._errors,
|
|
1555
|
-
_cstLeaves: ctx._cstLeaves,
|
|
1556
|
-
_cstChildren: ctx._cstChildren,
|
|
1557
|
-
_cstRawChildren: ctx._cstRawChildren,
|
|
1558
|
-
_cstTriviaLog: ctx._cstTriviaLog,
|
|
1559
|
-
_triviaLog: ctx._triviaLog,
|
|
1560
|
-
_fields: ctx._fields,
|
|
1561
|
-
_cstBuf: ctx._cstBuf,
|
|
1562
|
-
_tolerant: ctx._tolerant,
|
|
1563
|
-
_sync: ctx._sync
|
|
1564
|
-
};
|
|
1565
|
-
ctx._probe = void 0;
|
|
1566
|
-
ctx._errors = void 0;
|
|
1567
|
-
ctx._cstLeaves = void 0;
|
|
1568
|
-
ctx._cstChildren = void 0;
|
|
1569
|
-
ctx._cstRawChildren = void 0;
|
|
1570
|
-
ctx._cstTriviaLog = void 0;
|
|
1571
|
-
ctx._triviaLog = void 0;
|
|
1572
|
-
ctx._fields = void 0;
|
|
1573
|
-
ctx._cstBuf = void 0;
|
|
1574
|
-
ctx._tolerant = void 0;
|
|
1575
|
-
ctx._sync = void 0;
|
|
1576
|
-
try {
|
|
1577
|
-
return sentinel.parse(input, pos, ctx).ok;
|
|
1578
|
-
} finally {
|
|
1579
|
-
ctx._probe = s._probe;
|
|
1580
|
-
ctx._errors = s._errors;
|
|
1581
|
-
ctx._cstLeaves = s._cstLeaves;
|
|
1582
|
-
ctx._cstChildren = s._cstChildren;
|
|
1583
|
-
ctx._cstRawChildren = s._cstRawChildren;
|
|
1584
|
-
ctx._cstTriviaLog = s._cstTriviaLog;
|
|
1585
|
-
ctx._triviaLog = s._triviaLog;
|
|
1586
|
-
ctx._fields = s._fields;
|
|
1587
|
-
ctx._cstBuf = s._cstBuf;
|
|
1588
|
-
ctx._tolerant = s._tolerant;
|
|
1589
|
-
ctx._sync = s._sync;
|
|
1590
|
-
}
|
|
1591
|
-
}
|
|
1592
|
-
function orSentinel(a, b) {
|
|
1593
|
-
if (b === void 0) return a;
|
|
1594
|
-
return {
|
|
1595
|
-
_tag: "orSentinel",
|
|
1596
|
-
_meta: { firstSet: { kind: "any" }, canMatchNewline: false, isTrivia: false },
|
|
1597
|
-
_def: { tag: "unknown" },
|
|
1598
|
-
parse(input, pos, ctx) {
|
|
1599
|
-
const ra = a.parse(input, pos, ctx);
|
|
1600
|
-
if (ra.ok) return ra;
|
|
1601
|
-
return b.parse(input, pos, ctx);
|
|
1602
|
-
}
|
|
1603
|
-
};
|
|
1604
|
-
}
|
|
1605
|
-
function firstSetSentinel(fs) {
|
|
1606
|
-
if (fs.kind !== "ranges" || fs.ranges.length === 0) return null;
|
|
1607
|
-
const ranges = fs.ranges;
|
|
1608
|
-
return {
|
|
1609
|
-
_tag: "firstSetSentinel",
|
|
1610
|
-
_meta: { firstSet: fs, canMatchNewline: false, isTrivia: false },
|
|
1611
|
-
_def: { tag: "unknown" },
|
|
1612
|
-
parse(input, pos) {
|
|
1613
|
-
const code = pos < input.length ? input.codePointAt(pos) : void 0;
|
|
1614
|
-
if (code !== void 0) {
|
|
1615
|
-
for (const r of ranges) {
|
|
1616
|
-
if (code >= r.lo && code <= r.hi) return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
1617
|
-
}
|
|
1618
|
-
}
|
|
1619
|
-
return { ok: false, expected: [], span: { start: pos, end: pos } };
|
|
1620
|
-
}
|
|
1621
|
-
};
|
|
1622
|
-
}
|
|
1623
|
-
function recoverScan(input, from, ctx, sync, expected) {
|
|
1624
|
-
let scanPos = from;
|
|
1625
|
-
while (scanPos < input.length && !probeAt(sync, input, scanPos, ctx)) scanPos++;
|
|
1626
|
-
const error = { _tag: "parseError", span: { start: from, end: scanPos }, expected };
|
|
1627
|
-
ctx._errors?.push(error);
|
|
1628
|
-
return { error, end: scanPos };
|
|
1629
|
-
}
|
|
1630
|
-
function matchesAt(sentinel, input, pos, ctx) {
|
|
1631
|
-
return probeAt(sentinel, input, pos, ctx);
|
|
1632
|
-
}
|
|
1633
|
-
function captureError(ctx, error) {
|
|
1634
|
-
if (cstCaptureActive(ctx)) pushCstChild(ctx, error, error);
|
|
1635
|
-
}
|
|
1636
|
-
var REC = { scan: recoverScan, at: matchesAt, or: orSentinel, sentinel: firstSetSentinel, capture: captureError };
|
|
1637
|
-
|
|
1638
1705
|
// src/combinators/sequence.ts
|
|
1639
1706
|
function sequence(...parsers) {
|
|
1640
1707
|
const meta = {
|
|
@@ -1736,69 +1803,6 @@ function sequence(...parsers) {
|
|
|
1736
1803
|
};
|
|
1737
1804
|
}
|
|
1738
1805
|
|
|
1739
|
-
// src/combinators/expect.ts
|
|
1740
|
-
function deriveExpected(c) {
|
|
1741
|
-
const def = c._def;
|
|
1742
|
-
switch (def.tag) {
|
|
1743
|
-
case "literal":
|
|
1744
|
-
return [JSON.stringify(def.value)];
|
|
1745
|
-
case "regex":
|
|
1746
|
-
return [`/${def.source}/`];
|
|
1747
|
-
case "keywords":
|
|
1748
|
-
return def.words.map((w) => JSON.stringify(w));
|
|
1749
|
-
case "label":
|
|
1750
|
-
return [def.label];
|
|
1751
|
-
case "choice":
|
|
1752
|
-
return def.parsers.flatMap(deriveExpected);
|
|
1753
|
-
case "sequence":
|
|
1754
|
-
return def.parsers.length > 0 ? deriveExpected(def.parsers[0]) : [];
|
|
1755
|
-
case "node":
|
|
1756
|
-
case "grammar":
|
|
1757
|
-
case "trivia":
|
|
1758
|
-
case "token":
|
|
1759
|
-
case "optional":
|
|
1760
|
-
case "many":
|
|
1761
|
-
case "oneOrMore":
|
|
1762
|
-
case "transform":
|
|
1763
|
-
case "not":
|
|
1764
|
-
return deriveExpected(def.parser);
|
|
1765
|
-
case "lazy": {
|
|
1766
|
-
const name = c._ruleName;
|
|
1767
|
-
try {
|
|
1768
|
-
return deriveExpected(def.thunk());
|
|
1769
|
-
} catch {
|
|
1770
|
-
return name ? [name] : [];
|
|
1771
|
-
}
|
|
1772
|
-
}
|
|
1773
|
-
default:
|
|
1774
|
-
return [];
|
|
1775
|
-
}
|
|
1776
|
-
}
|
|
1777
|
-
function expect(combinator, label2) {
|
|
1778
|
-
const expected = label2 !== void 0 ? [label2] : deriveExpected(combinator);
|
|
1779
|
-
const meta = {
|
|
1780
|
-
firstSet: combinator._meta.firstSet,
|
|
1781
|
-
canMatchNewline: combinator._meta.canMatchNewline,
|
|
1782
|
-
isTrivia: false
|
|
1783
|
-
};
|
|
1784
|
-
return {
|
|
1785
|
-
_tag: "expect",
|
|
1786
|
-
_meta: meta,
|
|
1787
|
-
_def: { tag: "expect", parser: combinator, label: label2, expected },
|
|
1788
|
-
parse(input, pos, ctx) {
|
|
1789
|
-
const result = combinator.parse(input, pos, ctx);
|
|
1790
|
-
if (result.ok) return result;
|
|
1791
|
-
const error = { _tag: "parseError", span: { start: pos, end: pos }, expected };
|
|
1792
|
-
ctx._errors?.push(error);
|
|
1793
|
-
if (ctx._tolerant) captureError(ctx, error);
|
|
1794
|
-
return { ok: true, value: error, span: { start: pos, end: pos } };
|
|
1795
|
-
}
|
|
1796
|
-
};
|
|
1797
|
-
}
|
|
1798
|
-
function isParseError(value) {
|
|
1799
|
-
return typeof value === "object" && value !== null && value._tag === "parseError";
|
|
1800
|
-
}
|
|
1801
|
-
|
|
1802
1806
|
// src/combinators/repeat.ts
|
|
1803
1807
|
function repItem(combinator, input, cur, ctx) {
|
|
1804
1808
|
const mark = saveTriviaMark(ctx);
|
|
@@ -4629,6 +4633,21 @@ function emitDisjointArm(p, ctx, pos, valV, endV) {
|
|
|
4629
4633
|
`${ind(ctx)}${endV} = ${endVar}`
|
|
4630
4634
|
];
|
|
4631
4635
|
}
|
|
4636
|
+
function emitDisjointArmGated(def, i, ctx, pos, valV, endV) {
|
|
4637
|
+
const p = def.parsers[i];
|
|
4638
|
+
const gate = def.gates[i];
|
|
4639
|
+
if (!gate) return emitDisjointArm(p, ctx, pos, valV, endV);
|
|
4640
|
+
const gateIdx = ctx.mapFns.length;
|
|
4641
|
+
ctx.mapFns.push(gate);
|
|
4642
|
+
ctx.mapFnSrcs.push(def.gateSrcs?.[i] ?? null);
|
|
4643
|
+
const gateCond = `${mfRef(ctx)}[${gateIdx}](_ctx.state)`;
|
|
4644
|
+
const stmts = [`${ind(ctx)}if (${gateCond}) {`];
|
|
4645
|
+
ctx.indent++;
|
|
4646
|
+
stmts.push(...emitDisjointArm(p, ctx, pos, valV, endV));
|
|
4647
|
+
ctx.indent--;
|
|
4648
|
+
stmts.push(`${ind(ctx)}} else { ${failArrBody(ctx, deriveExpectedArr([p]), pos)} }`);
|
|
4649
|
+
return stmts;
|
|
4650
|
+
}
|
|
4632
4651
|
function emitChoice(def, ctx, pos) {
|
|
4633
4652
|
const allExpected = deriveExpectedArr(def.parsers);
|
|
4634
4653
|
if (def.disjoint) {
|
|
@@ -4644,12 +4663,11 @@ function emitChoice(def, ctx, pos) {
|
|
|
4644
4663
|
stmts.push(`${ind(ctx)}switch (${codeV}) {`);
|
|
4645
4664
|
ctx.indent++;
|
|
4646
4665
|
for (let i = 0; i < def.parsers.length; i++) {
|
|
4647
|
-
const p = def.parsers[i];
|
|
4648
4666
|
for (const cp of plan.cases[i]) stmts.push(`${ind(ctx)}case ${cp}:`);
|
|
4649
4667
|
stmts.push(`${ind(ctx)}{`);
|
|
4650
4668
|
ctx.indent++;
|
|
4651
4669
|
stmts.push(
|
|
4652
|
-
...
|
|
4670
|
+
...emitDisjointArmGated(def, i, ctx, pos, valV, endV),
|
|
4653
4671
|
`${ind(ctx)}break`
|
|
4654
4672
|
);
|
|
4655
4673
|
ctx.indent--;
|
|
@@ -4661,13 +4679,14 @@ function emitChoice(def, ctx, pos) {
|
|
|
4661
4679
|
return { stmts, valueVar: valV, endVar: endV };
|
|
4662
4680
|
}
|
|
4663
4681
|
let first = true;
|
|
4664
|
-
for (
|
|
4682
|
+
for (let i = 0; i < def.parsers.length; i++) {
|
|
4683
|
+
const p = def.parsers[i];
|
|
4665
4684
|
const cond = firstSetCond(codeV, p._meta.firstSet);
|
|
4666
4685
|
const kw = first ? "if" : "else if";
|
|
4667
4686
|
first = false;
|
|
4668
4687
|
stmts.push(`${ind(ctx)}${kw} (${cond}) {`);
|
|
4669
4688
|
ctx.indent++;
|
|
4670
|
-
stmts.push(...
|
|
4689
|
+
stmts.push(...emitDisjointArmGated(def, i, ctx, pos, valV, endV));
|
|
4671
4690
|
ctx.indent--;
|
|
4672
4691
|
stmts.push(`${ind(ctx)}}`);
|
|
4673
4692
|
}
|
|
@@ -6326,6 +6345,34 @@ function evalRuleMapIR(ir) {
|
|
|
6326
6345
|
n._def.buildSrc = src;
|
|
6327
6346
|
return n;
|
|
6328
6347
|
};
|
|
6348
|
+
const _gch = (items) => {
|
|
6349
|
+
const gateSrcs = [];
|
|
6350
|
+
const arms = items.map((it) => {
|
|
6351
|
+
if (Array.isArray(it)) {
|
|
6352
|
+
const [src, comb] = it;
|
|
6353
|
+
gateSrcs.push(src);
|
|
6354
|
+
let gate;
|
|
6355
|
+
try {
|
|
6356
|
+
gate = (0, eval)(`(${src})`);
|
|
6357
|
+
} catch {
|
|
6358
|
+
gate = () => {
|
|
6359
|
+
throw new Error("IR gate fn not materialized");
|
|
6360
|
+
};
|
|
6361
|
+
}
|
|
6362
|
+
return { gate, combinator: comb };
|
|
6363
|
+
}
|
|
6364
|
+
gateSrcs.push(null);
|
|
6365
|
+
return it;
|
|
6366
|
+
});
|
|
6367
|
+
const c = choice(...arms);
|
|
6368
|
+
const gates = c._def.gates;
|
|
6369
|
+
if (gates && gates.length !== gateSrcs.length) {
|
|
6370
|
+
throw new Error(`_gch: gateSrcs length ${gateSrcs.length} != choice gates length ${gates.length}`);
|
|
6371
|
+
}
|
|
6372
|
+
;
|
|
6373
|
+
c._def.gateSrcs = gateSrcs;
|
|
6374
|
+
return c;
|
|
6375
|
+
};
|
|
6329
6376
|
const fn = new Function(
|
|
6330
6377
|
"rules",
|
|
6331
6378
|
"ref",
|
|
@@ -6351,6 +6398,7 @@ function evalRuleMapIR(ir) {
|
|
|
6351
6398
|
"expect",
|
|
6352
6399
|
"_tf",
|
|
6353
6400
|
"_nd",
|
|
6401
|
+
"_gch",
|
|
6354
6402
|
`return (${ir})`
|
|
6355
6403
|
);
|
|
6356
6404
|
const map = fn(
|
|
@@ -6377,7 +6425,8 @@ function evalRuleMapIR(ir) {
|
|
|
6377
6425
|
field,
|
|
6378
6426
|
expect,
|
|
6379
6427
|
_tf,
|
|
6380
|
-
_nd
|
|
6428
|
+
_nd,
|
|
6429
|
+
_gch
|
|
6381
6430
|
);
|
|
6382
6431
|
return Object.entries(map);
|
|
6383
6432
|
}
|
|
@@ -6489,8 +6538,16 @@ ${body}
|
|
|
6489
6538
|
case "sequence":
|
|
6490
6539
|
return `sequence(${def.parsers.map(kid).join(", ")})`;
|
|
6491
6540
|
case "choice": {
|
|
6492
|
-
|
|
6493
|
-
return `choice(${def.parsers.map(kid).join(", ")})`;
|
|
6541
|
+
const gates = def.gates;
|
|
6542
|
+
if (gates.every((g) => g === null)) return `choice(${def.parsers.map(kid).join(", ")})`;
|
|
6543
|
+
const gateSrcs = def.gateSrcs;
|
|
6544
|
+
const items = def.parsers.map((p, i) => {
|
|
6545
|
+
if (gates[i] === null) return kid(p);
|
|
6546
|
+
const src = gateSrcs?.[i];
|
|
6547
|
+
if (src == null) throw new Unserializable("choice gate() has no captured source");
|
|
6548
|
+
return `[${JSON.stringify(src)}, ${kid(p)}]`;
|
|
6549
|
+
});
|
|
6550
|
+
return `_gch([${items.join(", ")}])`;
|
|
6494
6551
|
}
|
|
6495
6552
|
case "many":
|
|
6496
6553
|
return `many(${kid(def.parser)})`;
|