Files
infocom-systems-design/node_modules/@chevrotain/gast/lib/src/helpers.js
2025-10-03 22:27:28 +03:00

79 lines
2.7 KiB
JavaScript

import { every, includes, some } from "lodash-es";
import { AbstractProduction, Alternation, Alternative, NonTerminal, Option, Repetition, RepetitionMandatory, RepetitionMandatoryWithSeparator, RepetitionWithSeparator, Rule, Terminal, } from "./model.js";
export function isSequenceProd(prod) {
return (prod instanceof Alternative ||
prod instanceof Option ||
prod instanceof Repetition ||
prod instanceof RepetitionMandatory ||
prod instanceof RepetitionMandatoryWithSeparator ||
prod instanceof RepetitionWithSeparator ||
prod instanceof Terminal ||
prod instanceof Rule);
}
export function isOptionalProd(prod, alreadyVisited = []) {
const isDirectlyOptional = prod instanceof Option ||
prod instanceof Repetition ||
prod instanceof RepetitionWithSeparator;
if (isDirectlyOptional) {
return true;
}
// note that this can cause infinite loop if one optional empty TOP production has a cyclic dependency with another
// empty optional top rule
// may be indirectly optional ((A?B?C?) | (D?E?F?))
if (prod instanceof Alternation) {
// for OR its enough for just one of the alternatives to be optional
return some(prod.definition, (subProd) => {
return isOptionalProd(subProd, alreadyVisited);
});
}
else if (prod instanceof NonTerminal && includes(alreadyVisited, prod)) {
// avoiding stack overflow due to infinite recursion
return false;
}
else if (prod instanceof AbstractProduction) {
if (prod instanceof NonTerminal) {
alreadyVisited.push(prod);
}
return every(prod.definition, (subProd) => {
return isOptionalProd(subProd, alreadyVisited);
});
}
else {
return false;
}
}
export function isBranchingProd(prod) {
return prod instanceof Alternation;
}
export function getProductionDslName(prod) {
/* istanbul ignore else */
if (prod instanceof NonTerminal) {
return "SUBRULE";
}
else if (prod instanceof Option) {
return "OPTION";
}
else if (prod instanceof Alternation) {
return "OR";
}
else if (prod instanceof RepetitionMandatory) {
return "AT_LEAST_ONE";
}
else if (prod instanceof RepetitionMandatoryWithSeparator) {
return "AT_LEAST_ONE_SEP";
}
else if (prod instanceof RepetitionWithSeparator) {
return "MANY_SEP";
}
else if (prod instanceof Repetition) {
return "MANY";
}
else if (prod instanceof Terminal) {
return "CONSUME";
/* c8 ignore next 3 */
}
else {
throw Error("non exhaustive match");
}
}
//# sourceMappingURL=helpers.js.map