@scinorandex/sparse
Version:
Yet another parser generator
59 lines • 3.53 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildStates = exports.tableLexerGenerator = exports.TableTokenType = void 0;
const slex_1 = require("@scinorandex/slex");
const parser_1 = require("../parser");
var TableTokenType;
(function (TableTokenType) {
TableTokenType[TableTokenType["PRODUCTION_NAME"] = 0] = "PRODUCTION_NAME";
TableTokenType[TableTokenType["TOKEN_NAME"] = 1] = "TOKEN_NAME";
TableTokenType[TableTokenType["COMMA"] = 2] = "COMMA";
TableTokenType[TableTokenType["EQUALS"] = 3] = "EQUALS";
TableTokenType[TableTokenType["SHIFT_ACTION"] = 4] = "SHIFT_ACTION";
TableTokenType[TableTokenType["REDUCE_ACTION"] = 5] = "REDUCE_ACTION";
TableTokenType[TableTokenType["GOTO_ACTION"] = 6] = "GOTO_ACTION";
TableTokenType[TableTokenType["EOF"] = 7] = "EOF";
})(TableTokenType || (exports.TableTokenType = TableTokenType = {}));
exports.tableLexerGenerator = new slex_1.Slex({
EOF_TYPE: TableTokenType.EOF,
isHigherPrecedence: () => false,
});
exports.tableLexerGenerator.addRule("lowercase", "a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z");
exports.tableLexerGenerator.addRule("uppercase", "A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z");
exports.tableLexerGenerator.addRule("letter", "${lowercase} | ${uppercase}");
exports.tableLexerGenerator.addRule("digit", "0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9");
exports.tableLexerGenerator.addRule("alphanumeric", "${letter} | ${digit}");
exports.tableLexerGenerator.addRule("identifier", "(${letter} | ${digit} | $_)*");
exports.tableLexerGenerator.addRule("comma", "$,", TableTokenType.COMMA);
exports.tableLexerGenerator.addRule("equals", "$=", TableTokenType.EQUALS);
exports.tableLexerGenerator.addRule("production_name", "$< ${identifier} $>", TableTokenType.PRODUCTION_NAME);
exports.tableLexerGenerator.addRule("token_name", "$[ ${identifier} $]", TableTokenType.TOKEN_NAME);
exports.tableLexerGenerator.addRule("shift_action", "s(${digit})*", TableTokenType.SHIFT_ACTION);
exports.tableLexerGenerator.addRule("reduce_action", "r(${digit})*", TableTokenType.REDUCE_ACTION);
exports.tableLexerGenerator.addRule("goto_action", "${digit}(${digit})*", TableTokenType.GOTO_ACTION);
const buildStates = (grammar) => grammar.split("\n").map((line) => {
const lexer = exports.tableLexerGenerator.generate(line, () => ({}));
const state = new parser_1.TableState();
const expect = (type) => {
const token = lexer.peekNextToken();
if (token.type !== type)
throw new Error(`Expected ${TableTokenType[type]}, got ${TableTokenType[token.type]}`);
lexer.getNextToken();
};
while (lexer.hasNextToken()) {
const token = lexer.getNextToken();
expect(TableTokenType.EQUALS);
const value = lexer.getNextToken();
const setting = token.type === TableTokenType.PRODUCTION_NAME
? { type: "goto", value: parseInt(value.lexeme) }
: value.type === TableTokenType.REDUCE_ACTION
? { type: "reduce", value: parseInt(value.lexeme.substring(1)) }
: { type: "shift", value: parseInt(value.lexeme.substring(1)) };
state.actions.set(token.lexeme, setting);
if (lexer.peekNextToken().type == TableTokenType.COMMA)
lexer.getNextToken();
}
return state;
});
exports.buildStates = buildStates;
//# sourceMappingURL=handwritten.js.map