parseman 0.26.0 → 0.26.1
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/index.cjs +186 -167
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +186 -167
- package/dist/index.js.map +4 -4
- package/dist/plugin/index.cjs +182 -163
- package/dist/plugin/index.cjs.map +4 -4
- package/dist/plugin/index.js +182 -163
- package/dist/plugin/index.js.map +4 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -836,12 +836,163 @@ function keywords(words, opts = {}) {
|
|
|
836
836
|
};
|
|
837
837
|
}
|
|
838
838
|
|
|
839
|
+
// src/recovery/scan.ts
|
|
840
|
+
function probeAt(sentinel, input, pos, ctx) {
|
|
841
|
+
const s = {
|
|
842
|
+
_probe: ctx._probe,
|
|
843
|
+
_errors: ctx._errors,
|
|
844
|
+
_cstLeaves: ctx._cstLeaves,
|
|
845
|
+
_cstChildren: ctx._cstChildren,
|
|
846
|
+
_cstRawChildren: ctx._cstRawChildren,
|
|
847
|
+
_cstTriviaLog: ctx._cstTriviaLog,
|
|
848
|
+
_triviaLog: ctx._triviaLog,
|
|
849
|
+
_fields: ctx._fields,
|
|
850
|
+
_cstBuf: ctx._cstBuf,
|
|
851
|
+
_tolerant: ctx._tolerant,
|
|
852
|
+
_sync: ctx._sync
|
|
853
|
+
};
|
|
854
|
+
ctx._probe = void 0;
|
|
855
|
+
ctx._errors = void 0;
|
|
856
|
+
ctx._cstLeaves = void 0;
|
|
857
|
+
ctx._cstChildren = void 0;
|
|
858
|
+
ctx._cstRawChildren = void 0;
|
|
859
|
+
ctx._cstTriviaLog = void 0;
|
|
860
|
+
ctx._triviaLog = void 0;
|
|
861
|
+
ctx._fields = void 0;
|
|
862
|
+
ctx._cstBuf = void 0;
|
|
863
|
+
ctx._tolerant = void 0;
|
|
864
|
+
ctx._sync = void 0;
|
|
865
|
+
try {
|
|
866
|
+
return sentinel.parse(input, pos, ctx).ok;
|
|
867
|
+
} finally {
|
|
868
|
+
ctx._probe = s._probe;
|
|
869
|
+
ctx._errors = s._errors;
|
|
870
|
+
ctx._cstLeaves = s._cstLeaves;
|
|
871
|
+
ctx._cstChildren = s._cstChildren;
|
|
872
|
+
ctx._cstRawChildren = s._cstRawChildren;
|
|
873
|
+
ctx._cstTriviaLog = s._cstTriviaLog;
|
|
874
|
+
ctx._triviaLog = s._triviaLog;
|
|
875
|
+
ctx._fields = s._fields;
|
|
876
|
+
ctx._cstBuf = s._cstBuf;
|
|
877
|
+
ctx._tolerant = s._tolerant;
|
|
878
|
+
ctx._sync = s._sync;
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
function orSentinel(a, b) {
|
|
882
|
+
if (b === void 0) return a;
|
|
883
|
+
return {
|
|
884
|
+
_tag: "orSentinel",
|
|
885
|
+
_meta: { firstSet: { kind: "any" }, canMatchNewline: false, isTrivia: false },
|
|
886
|
+
_def: { tag: "unknown" },
|
|
887
|
+
parse(input, pos, ctx) {
|
|
888
|
+
const ra = a.parse(input, pos, ctx);
|
|
889
|
+
if (ra.ok) return ra;
|
|
890
|
+
return b.parse(input, pos, ctx);
|
|
891
|
+
}
|
|
892
|
+
};
|
|
893
|
+
}
|
|
894
|
+
function firstSetSentinel(fs) {
|
|
895
|
+
if (fs.kind !== "ranges" || fs.ranges.length === 0) return null;
|
|
896
|
+
const ranges = fs.ranges;
|
|
897
|
+
return {
|
|
898
|
+
_tag: "firstSetSentinel",
|
|
899
|
+
_meta: { firstSet: fs, canMatchNewline: false, isTrivia: false },
|
|
900
|
+
_def: { tag: "unknown" },
|
|
901
|
+
parse(input, pos) {
|
|
902
|
+
const code = pos < input.length ? input.codePointAt(pos) : void 0;
|
|
903
|
+
if (code !== void 0) {
|
|
904
|
+
for (const r of ranges) {
|
|
905
|
+
if (code >= r.lo && code <= r.hi) return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
return { ok: false, expected: [], span: { start: pos, end: pos } };
|
|
909
|
+
}
|
|
910
|
+
};
|
|
911
|
+
}
|
|
912
|
+
function recoverScan(input, from, ctx, sync, expected) {
|
|
913
|
+
let scanPos = from;
|
|
914
|
+
while (scanPos < input.length && !probeAt(sync, input, scanPos, ctx)) scanPos++;
|
|
915
|
+
const error = { _tag: "parseError", span: { start: from, end: scanPos }, expected };
|
|
916
|
+
ctx._errors?.push(error);
|
|
917
|
+
return { error, end: scanPos };
|
|
918
|
+
}
|
|
919
|
+
function matchesAt(sentinel, input, pos, ctx) {
|
|
920
|
+
return probeAt(sentinel, input, pos, ctx);
|
|
921
|
+
}
|
|
922
|
+
function captureError(ctx, error) {
|
|
923
|
+
if (cstCaptureActive(ctx)) pushCstChild(ctx, error, error);
|
|
924
|
+
}
|
|
925
|
+
var REC = { scan: recoverScan, at: matchesAt, or: orSentinel, sentinel: firstSetSentinel, capture: captureError };
|
|
926
|
+
|
|
927
|
+
// src/combinators/expect.ts
|
|
928
|
+
function deriveExpected(c) {
|
|
929
|
+
const def = c._def;
|
|
930
|
+
switch (def.tag) {
|
|
931
|
+
case "literal":
|
|
932
|
+
return [JSON.stringify(def.value)];
|
|
933
|
+
case "regex":
|
|
934
|
+
return [`/${def.source}/`];
|
|
935
|
+
case "keywords":
|
|
936
|
+
return def.words.map((w) => JSON.stringify(w));
|
|
937
|
+
case "label":
|
|
938
|
+
return [def.label];
|
|
939
|
+
case "choice":
|
|
940
|
+
return def.parsers.flatMap(deriveExpected);
|
|
941
|
+
case "sequence":
|
|
942
|
+
return def.parsers.length > 0 ? deriveExpected(def.parsers[0]) : [];
|
|
943
|
+
case "node":
|
|
944
|
+
case "grammar":
|
|
945
|
+
case "trivia":
|
|
946
|
+
case "token":
|
|
947
|
+
case "optional":
|
|
948
|
+
case "many":
|
|
949
|
+
case "oneOrMore":
|
|
950
|
+
case "transform":
|
|
951
|
+
case "not":
|
|
952
|
+
return deriveExpected(def.parser);
|
|
953
|
+
case "lazy": {
|
|
954
|
+
const name = c._ruleName;
|
|
955
|
+
try {
|
|
956
|
+
return deriveExpected(def.thunk());
|
|
957
|
+
} catch {
|
|
958
|
+
return name ? [name] : [];
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
default:
|
|
962
|
+
return [];
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
function expect(combinator, label2) {
|
|
966
|
+
const expected = label2 !== void 0 ? [label2] : deriveExpected(combinator);
|
|
967
|
+
const meta = {
|
|
968
|
+
firstSet: combinator._meta.firstSet,
|
|
969
|
+
canMatchNewline: combinator._meta.canMatchNewline,
|
|
970
|
+
isTrivia: false
|
|
971
|
+
};
|
|
972
|
+
return {
|
|
973
|
+
_tag: "expect",
|
|
974
|
+
_meta: meta,
|
|
975
|
+
_def: { tag: "expect", parser: combinator, label: label2, expected },
|
|
976
|
+
parse(input, pos, ctx) {
|
|
977
|
+
const result = combinator.parse(input, pos, ctx);
|
|
978
|
+
if (result.ok) return result;
|
|
979
|
+
const error = { _tag: "parseError", span: { start: pos, end: pos }, expected };
|
|
980
|
+
ctx._errors?.push(error);
|
|
981
|
+
if (ctx._tolerant) captureError(ctx, error);
|
|
982
|
+
return { ok: true, value: error, span: { start: pos, end: pos } };
|
|
983
|
+
}
|
|
984
|
+
};
|
|
985
|
+
}
|
|
986
|
+
function isParseError(value) {
|
|
987
|
+
return typeof value === "object" && value !== null && value._tag === "parseError";
|
|
988
|
+
}
|
|
989
|
+
|
|
839
990
|
// src/combinators/choice.ts
|
|
840
991
|
function choice(...args) {
|
|
841
992
|
const parsers = args.map((a) => "gate" in a ? a.combinator : a);
|
|
842
993
|
const gates = args.map((a) => "gate" in a ? a.gate : null);
|
|
843
994
|
const hasGates = gates.some((g) => g !== null);
|
|
844
|
-
const disjoint =
|
|
995
|
+
const disjoint = areDisjoint(parsers.map((p) => p._meta.firstSet)) && parsers.every((p) => !matchesEmpty(p));
|
|
845
996
|
let combined = { kind: "empty" };
|
|
846
997
|
for (const p of parsers) combined = union(combined, p._meta.firstSet);
|
|
847
998
|
const meta = {
|
|
@@ -880,17 +1031,21 @@ function choice(...args) {
|
|
|
880
1031
|
const expected = [];
|
|
881
1032
|
if (disjoint && pos < input.length) {
|
|
882
1033
|
const code = input.codePointAt(pos);
|
|
883
|
-
let
|
|
884
|
-
if (
|
|
885
|
-
for (
|
|
886
|
-
if (inFirstSet(code,
|
|
887
|
-
|
|
1034
|
+
let idx = code < 128 ? asciiDispatch[code] : -1;
|
|
1035
|
+
if (idx < 0) {
|
|
1036
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1037
|
+
if (inFirstSet(code, parsers[i]._meta.firstSet)) {
|
|
1038
|
+
idx = i;
|
|
888
1039
|
break;
|
|
889
1040
|
}
|
|
890
1041
|
}
|
|
891
1042
|
}
|
|
892
|
-
if (
|
|
893
|
-
const
|
|
1043
|
+
if (idx >= 0) {
|
|
1044
|
+
const gate = gates[idx];
|
|
1045
|
+
if (gate && !gate(ctx.state)) {
|
|
1046
|
+
return { ok: false, expected: deriveExpected(parsers[idx]), span: { start: pos, end: pos } };
|
|
1047
|
+
}
|
|
1048
|
+
const result = parsers[idx].parse(input, pos, ctx);
|
|
894
1049
|
if (result.ok) return result;
|
|
895
1050
|
expected.push(...result.expected);
|
|
896
1051
|
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
@@ -1071,13 +1226,13 @@ function areDisjoint(sets) {
|
|
|
1071
1226
|
return true;
|
|
1072
1227
|
}
|
|
1073
1228
|
function buildAsciiDispatch(parsers) {
|
|
1074
|
-
const table = Array(128).fill(
|
|
1075
|
-
for (
|
|
1076
|
-
const fs =
|
|
1229
|
+
const table = Array(128).fill(-1);
|
|
1230
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1231
|
+
const fs = parsers[i]._meta.firstSet;
|
|
1077
1232
|
if (fs.kind !== "ranges") continue;
|
|
1078
1233
|
for (const { lo, hi } of fs.ranges) {
|
|
1079
1234
|
for (let code = Math.max(0, lo); code <= Math.min(127, hi); code++) {
|
|
1080
|
-
table[code] =
|
|
1235
|
+
table[code] = i;
|
|
1081
1236
|
}
|
|
1082
1237
|
}
|
|
1083
1238
|
}
|
|
@@ -1459,94 +1614,6 @@ function scanBlockComment(input, cur) {
|
|
|
1459
1614
|
return close === -1 ? cur : close + 2;
|
|
1460
1615
|
}
|
|
1461
1616
|
|
|
1462
|
-
// src/recovery/scan.ts
|
|
1463
|
-
function probeAt(sentinel, input, pos, ctx) {
|
|
1464
|
-
const s = {
|
|
1465
|
-
_probe: ctx._probe,
|
|
1466
|
-
_errors: ctx._errors,
|
|
1467
|
-
_cstLeaves: ctx._cstLeaves,
|
|
1468
|
-
_cstChildren: ctx._cstChildren,
|
|
1469
|
-
_cstRawChildren: ctx._cstRawChildren,
|
|
1470
|
-
_cstTriviaLog: ctx._cstTriviaLog,
|
|
1471
|
-
_triviaLog: ctx._triviaLog,
|
|
1472
|
-
_fields: ctx._fields,
|
|
1473
|
-
_cstBuf: ctx._cstBuf,
|
|
1474
|
-
_tolerant: ctx._tolerant,
|
|
1475
|
-
_sync: ctx._sync
|
|
1476
|
-
};
|
|
1477
|
-
ctx._probe = void 0;
|
|
1478
|
-
ctx._errors = void 0;
|
|
1479
|
-
ctx._cstLeaves = void 0;
|
|
1480
|
-
ctx._cstChildren = void 0;
|
|
1481
|
-
ctx._cstRawChildren = void 0;
|
|
1482
|
-
ctx._cstTriviaLog = void 0;
|
|
1483
|
-
ctx._triviaLog = void 0;
|
|
1484
|
-
ctx._fields = void 0;
|
|
1485
|
-
ctx._cstBuf = void 0;
|
|
1486
|
-
ctx._tolerant = void 0;
|
|
1487
|
-
ctx._sync = void 0;
|
|
1488
|
-
try {
|
|
1489
|
-
return sentinel.parse(input, pos, ctx).ok;
|
|
1490
|
-
} finally {
|
|
1491
|
-
ctx._probe = s._probe;
|
|
1492
|
-
ctx._errors = s._errors;
|
|
1493
|
-
ctx._cstLeaves = s._cstLeaves;
|
|
1494
|
-
ctx._cstChildren = s._cstChildren;
|
|
1495
|
-
ctx._cstRawChildren = s._cstRawChildren;
|
|
1496
|
-
ctx._cstTriviaLog = s._cstTriviaLog;
|
|
1497
|
-
ctx._triviaLog = s._triviaLog;
|
|
1498
|
-
ctx._fields = s._fields;
|
|
1499
|
-
ctx._cstBuf = s._cstBuf;
|
|
1500
|
-
ctx._tolerant = s._tolerant;
|
|
1501
|
-
ctx._sync = s._sync;
|
|
1502
|
-
}
|
|
1503
|
-
}
|
|
1504
|
-
function orSentinel(a, b) {
|
|
1505
|
-
if (b === void 0) return a;
|
|
1506
|
-
return {
|
|
1507
|
-
_tag: "orSentinel",
|
|
1508
|
-
_meta: { firstSet: { kind: "any" }, canMatchNewline: false, isTrivia: false },
|
|
1509
|
-
_def: { tag: "unknown" },
|
|
1510
|
-
parse(input, pos, ctx) {
|
|
1511
|
-
const ra = a.parse(input, pos, ctx);
|
|
1512
|
-
if (ra.ok) return ra;
|
|
1513
|
-
return b.parse(input, pos, ctx);
|
|
1514
|
-
}
|
|
1515
|
-
};
|
|
1516
|
-
}
|
|
1517
|
-
function firstSetSentinel(fs) {
|
|
1518
|
-
if (fs.kind !== "ranges" || fs.ranges.length === 0) return null;
|
|
1519
|
-
const ranges = fs.ranges;
|
|
1520
|
-
return {
|
|
1521
|
-
_tag: "firstSetSentinel",
|
|
1522
|
-
_meta: { firstSet: fs, canMatchNewline: false, isTrivia: false },
|
|
1523
|
-
_def: { tag: "unknown" },
|
|
1524
|
-
parse(input, pos) {
|
|
1525
|
-
const code = pos < input.length ? input.codePointAt(pos) : void 0;
|
|
1526
|
-
if (code !== void 0) {
|
|
1527
|
-
for (const r of ranges) {
|
|
1528
|
-
if (code >= r.lo && code <= r.hi) return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
1529
|
-
}
|
|
1530
|
-
}
|
|
1531
|
-
return { ok: false, expected: [], span: { start: pos, end: pos } };
|
|
1532
|
-
}
|
|
1533
|
-
};
|
|
1534
|
-
}
|
|
1535
|
-
function recoverScan(input, from, ctx, sync, expected) {
|
|
1536
|
-
let scanPos = from;
|
|
1537
|
-
while (scanPos < input.length && !probeAt(sync, input, scanPos, ctx)) scanPos++;
|
|
1538
|
-
const error = { _tag: "parseError", span: { start: from, end: scanPos }, expected };
|
|
1539
|
-
ctx._errors?.push(error);
|
|
1540
|
-
return { error, end: scanPos };
|
|
1541
|
-
}
|
|
1542
|
-
function matchesAt(sentinel, input, pos, ctx) {
|
|
1543
|
-
return probeAt(sentinel, input, pos, ctx);
|
|
1544
|
-
}
|
|
1545
|
-
function captureError(ctx, error) {
|
|
1546
|
-
if (cstCaptureActive(ctx)) pushCstChild(ctx, error, error);
|
|
1547
|
-
}
|
|
1548
|
-
var REC = { scan: recoverScan, at: matchesAt, or: orSentinel, sentinel: firstSetSentinel, capture: captureError };
|
|
1549
|
-
|
|
1550
1617
|
// src/combinators/sequence.ts
|
|
1551
1618
|
function sequence(...parsers) {
|
|
1552
1619
|
const meta = {
|
|
@@ -1648,69 +1715,6 @@ function sequence(...parsers) {
|
|
|
1648
1715
|
};
|
|
1649
1716
|
}
|
|
1650
1717
|
|
|
1651
|
-
// src/combinators/expect.ts
|
|
1652
|
-
function deriveExpected(c) {
|
|
1653
|
-
const def = c._def;
|
|
1654
|
-
switch (def.tag) {
|
|
1655
|
-
case "literal":
|
|
1656
|
-
return [JSON.stringify(def.value)];
|
|
1657
|
-
case "regex":
|
|
1658
|
-
return [`/${def.source}/`];
|
|
1659
|
-
case "keywords":
|
|
1660
|
-
return def.words.map((w) => JSON.stringify(w));
|
|
1661
|
-
case "label":
|
|
1662
|
-
return [def.label];
|
|
1663
|
-
case "choice":
|
|
1664
|
-
return def.parsers.flatMap(deriveExpected);
|
|
1665
|
-
case "sequence":
|
|
1666
|
-
return def.parsers.length > 0 ? deriveExpected(def.parsers[0]) : [];
|
|
1667
|
-
case "node":
|
|
1668
|
-
case "grammar":
|
|
1669
|
-
case "trivia":
|
|
1670
|
-
case "token":
|
|
1671
|
-
case "optional":
|
|
1672
|
-
case "many":
|
|
1673
|
-
case "oneOrMore":
|
|
1674
|
-
case "transform":
|
|
1675
|
-
case "not":
|
|
1676
|
-
return deriveExpected(def.parser);
|
|
1677
|
-
case "lazy": {
|
|
1678
|
-
const name = c._ruleName;
|
|
1679
|
-
try {
|
|
1680
|
-
return deriveExpected(def.thunk());
|
|
1681
|
-
} catch {
|
|
1682
|
-
return name ? [name] : [];
|
|
1683
|
-
}
|
|
1684
|
-
}
|
|
1685
|
-
default:
|
|
1686
|
-
return [];
|
|
1687
|
-
}
|
|
1688
|
-
}
|
|
1689
|
-
function expect(combinator, label2) {
|
|
1690
|
-
const expected = label2 !== void 0 ? [label2] : deriveExpected(combinator);
|
|
1691
|
-
const meta = {
|
|
1692
|
-
firstSet: combinator._meta.firstSet,
|
|
1693
|
-
canMatchNewline: combinator._meta.canMatchNewline,
|
|
1694
|
-
isTrivia: false
|
|
1695
|
-
};
|
|
1696
|
-
return {
|
|
1697
|
-
_tag: "expect",
|
|
1698
|
-
_meta: meta,
|
|
1699
|
-
_def: { tag: "expect", parser: combinator, label: label2, expected },
|
|
1700
|
-
parse(input, pos, ctx) {
|
|
1701
|
-
const result = combinator.parse(input, pos, ctx);
|
|
1702
|
-
if (result.ok) return result;
|
|
1703
|
-
const error = { _tag: "parseError", span: { start: pos, end: pos }, expected };
|
|
1704
|
-
ctx._errors?.push(error);
|
|
1705
|
-
if (ctx._tolerant) captureError(ctx, error);
|
|
1706
|
-
return { ok: true, value: error, span: { start: pos, end: pos } };
|
|
1707
|
-
}
|
|
1708
|
-
};
|
|
1709
|
-
}
|
|
1710
|
-
function isParseError(value) {
|
|
1711
|
-
return typeof value === "object" && value !== null && value._tag === "parseError";
|
|
1712
|
-
}
|
|
1713
|
-
|
|
1714
1718
|
// src/combinators/repeat.ts
|
|
1715
1719
|
function repItem(combinator, input, cur, ctx) {
|
|
1716
1720
|
const mark = saveTriviaMark(ctx);
|
|
@@ -4541,6 +4545,21 @@ function emitDisjointArm(p, ctx, pos, valV, endV) {
|
|
|
4541
4545
|
`${ind(ctx)}${endV} = ${endVar}`
|
|
4542
4546
|
];
|
|
4543
4547
|
}
|
|
4548
|
+
function emitDisjointArmGated(def, i, ctx, pos, valV, endV) {
|
|
4549
|
+
const p = def.parsers[i];
|
|
4550
|
+
const gate = def.gates[i];
|
|
4551
|
+
if (!gate) return emitDisjointArm(p, ctx, pos, valV, endV);
|
|
4552
|
+
const gateIdx = ctx.mapFns.length;
|
|
4553
|
+
ctx.mapFns.push(gate);
|
|
4554
|
+
ctx.mapFnSrcs.push(def.gateSrcs?.[i] ?? null);
|
|
4555
|
+
const gateCond = `${mfRef(ctx)}[${gateIdx}](_ctx.state)`;
|
|
4556
|
+
const stmts = [`${ind(ctx)}if (${gateCond}) {`];
|
|
4557
|
+
ctx.indent++;
|
|
4558
|
+
stmts.push(...emitDisjointArm(p, ctx, pos, valV, endV));
|
|
4559
|
+
ctx.indent--;
|
|
4560
|
+
stmts.push(`${ind(ctx)}} else { ${failArrBody(ctx, deriveExpectedArr([p]), pos)} }`);
|
|
4561
|
+
return stmts;
|
|
4562
|
+
}
|
|
4544
4563
|
function emitChoice(def, ctx, pos) {
|
|
4545
4564
|
const allExpected = deriveExpectedArr(def.parsers);
|
|
4546
4565
|
if (def.disjoint) {
|
|
@@ -4556,12 +4575,11 @@ function emitChoice(def, ctx, pos) {
|
|
|
4556
4575
|
stmts.push(`${ind(ctx)}switch (${codeV}) {`);
|
|
4557
4576
|
ctx.indent++;
|
|
4558
4577
|
for (let i = 0; i < def.parsers.length; i++) {
|
|
4559
|
-
const p = def.parsers[i];
|
|
4560
4578
|
for (const cp of plan.cases[i]) stmts.push(`${ind(ctx)}case ${cp}:`);
|
|
4561
4579
|
stmts.push(`${ind(ctx)}{`);
|
|
4562
4580
|
ctx.indent++;
|
|
4563
4581
|
stmts.push(
|
|
4564
|
-
...
|
|
4582
|
+
...emitDisjointArmGated(def, i, ctx, pos, valV, endV),
|
|
4565
4583
|
`${ind(ctx)}break`
|
|
4566
4584
|
);
|
|
4567
4585
|
ctx.indent--;
|
|
@@ -4573,13 +4591,14 @@ function emitChoice(def, ctx, pos) {
|
|
|
4573
4591
|
return { stmts, valueVar: valV, endVar: endV };
|
|
4574
4592
|
}
|
|
4575
4593
|
let first = true;
|
|
4576
|
-
for (
|
|
4594
|
+
for (let i = 0; i < def.parsers.length; i++) {
|
|
4595
|
+
const p = def.parsers[i];
|
|
4577
4596
|
const cond = firstSetCond(codeV, p._meta.firstSet);
|
|
4578
4597
|
const kw = first ? "if" : "else if";
|
|
4579
4598
|
first = false;
|
|
4580
4599
|
stmts.push(`${ind(ctx)}${kw} (${cond}) {`);
|
|
4581
4600
|
ctx.indent++;
|
|
4582
|
-
stmts.push(...
|
|
4601
|
+
stmts.push(...emitDisjointArmGated(def, i, ctx, pos, valV, endV));
|
|
4583
4602
|
ctx.indent--;
|
|
4584
4603
|
stmts.push(`${ind(ctx)}}`);
|
|
4585
4604
|
}
|