@scinorandex/sparse
Version:
Yet another parser generator
65 lines • 2.31 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildStates = void 0;
const selfhosted_1 = require("../meta/selfhosted");
const parser_1 = require("../parser");
const states_1 = require("./states");
class StateNode extends selfhosted_1.BaseNode {
constructor(items) {
super();
this.items = items;
}
toTableState() {
const state = new parser_1.TableState();
for (const item of this.items.getItems()) {
const key = item.type === "terminal" ? `[${item.name.lexeme}]` : `<${item.name.lexeme}>`;
state.actions.set(key, item.action);
}
return state;
}
}
class ItemNode extends selfhosted_1.BaseNode {
constructor(type, name, action) {
super();
this.type = type;
this.name = name;
this.action = action;
}
}
const reducers = {
program: (bag) => bag.states,
states: (bag) => {
if (bag.rest == null)
return new selfhosted_1.ListNode([new StateNode(bag.state)]);
else
return bag.rest.add(new StateNode(bag.state));
},
items: (bag) => {
if (bag.rest == null)
return new selfhosted_1.ListNode([bag.item]);
else
return bag.rest.add(bag.item);
},
terminal: (bag) => {
const action = {
type: bag.action.lexeme.startsWith("s") ? "shift" : "reduce",
value: parseInt(bag.action.lexeme.substring(1)),
};
return new ItemNode("terminal", bag.name, action);
},
variable: (bag) => {
const action = { type: "goto", value: parseInt(bag.state.lexeme) };
return new ItemNode("variable", bag.name, action);
},
};
const buildStates = (grammar) => {
const lexer = selfhosted_1.grammarLexerGenerator.generate(grammar, () => ({}));
const parserGenerator = (0, selfhosted_1.getSelfHostedParserGenerator)(states_1.selfhosted);
const parser = parserGenerator.generate(lexer, {
reducer: ({ bag, name }) => reducers[name !== null && name !== void 0 ? name : ""](bag),
});
const parsingResult = parser.parse().result.getItemsReversed();
return parsingResult.map((state) => state.toTableState());
};
exports.buildStates = buildStates;
//# sourceMappingURL=selfhosted.js.map