parjs
Version:
Library for building parsers using combinators.
50 lines • 1.82 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.or = void 0;
const combinated_1 = require("../combinated");
const result_1 = require("../result");
const wrap_implicit_1 = require("../wrap-implicit");
class Or extends combinated_1.Combinated {
constructor(source, _alts) {
super(source);
this._alts = _alts;
this.type = "or";
this._altNames = [this.source, ...this._alts].map(x => `'${x.expecting}' (${x.type})`);
this.expecting = `expecting one of: ${this._altNames.join(", ")}`;
}
_apply(ps) {
const { position } = ps;
const resolvedAlts = [this.source, ...this._alts];
const allExpectations = resolvedAlts.map(x => x.expecting);
// eslint-disable-next-line @typescript-eslint/prefer-for-of
for (let i = 0; i < resolvedAlts.length; i++) {
// go over each alternative.
const cur = resolvedAlts[i];
// apply it on the current state.
cur.apply(ps);
if (ps.isOk) {
// if success, return. The PS records the result.
return;
}
else if (ps.isSoft) {
// backtrack to the original position and try again.
ps.position = position;
allExpectations[i] = ps.reason;
}
else {
// propagate hard failure
return;
}
}
ps.reason = allExpectations.join(" OR ");
ps.kind = result_1.ResultKind.SoftFail;
}
}
function or(...alts) {
const resolvedAlts = alts.map(wrap_implicit_1.wrapImplicit);
return (source) => {
return new Or((0, wrap_implicit_1.wrapImplicit)(source), resolvedAlts);
};
}
exports.or = or;
//# sourceMappingURL=or.js.map