UNPKG

jscc-parser

Version:

A LALR(1) Parser Generator for JavaScript written in JavaScript.

143 lines (130 loc) 5.22 kB
/* * Universal module definition for integrity. */ (function(root, factory) { /* istanbul ignore next */ if (typeof define === 'function' && define.amd) { define(['require', './global', './log/log', './enums/SYM'], factory); } else if (typeof module === 'object' && module.exports) { module.exports = factory(require); } else { root.jsccintegrity = factory(function(mod) { return root["jscc" + mod.split("/").pop()]; }); } }(this, /** * @param {reqParameter} require * @param {...*} others * @returns {jscc.integrity} */ function(require, others) { //>>excludeStart("closure", pragmas.closure); var jscc = {}; var has = /** @type {hasObject} */ (require("./localHas")); //>>excludeEnd("closure"); var log, global = /** @type {jscc.global} */ (require("./global")), SYM = require("./enums/SYM"); /** * @suppress {uselessCode} */ (function() { if (has("node")) { log = /** @type {jscc.log} */ (require("./log/logNode")); } else { log = /** @type {jscc.log} */ (require("./log/log")); } })(); /** * Error-checking functions. * @module {jscc.integrity} jscc/integrity * @requires module:jscc/global * @requires module:jscc/log/log */ /** * @constructor */ jscc.integrity = function() { }; jscc.integrity.prototype = { /** * Checks the {@link jscc.global.symbols} array for * nonterminating, undefined symbols. Logs an error if * any such symbols are found. */ undef: function() { for (var i = 0; i < global.symbols.length; i++) { if (global.symbols[i].kind == SYM.NONTERM && global.symbols[i].defined == false) { log.error("Call to undefined non-terminal \"" + global.symbols[i].label + "\""); } } }, /** * Checks the {@link jscc.global.symbols} and * {@link jscc.global.productions} arrays for * unreachable, nonterminating symbols. Logs a warning * if any such symbols are found. */ unreachable: function() { var stack = []; var reachable = []; var i, j, k, l; for (i = 0; i < global.symbols.length; i++) { if (global.symbols[i].kind == SYM.NONTERM) { break; } } if (i == global.symbols.length) { return; } stack.push(i); reachable.push(i); while (stack.length > 0) { i = stack.pop(); for (j = 0; j < global.symbols[i].prods.length; j++) { for (k = 0; k < global.productions[global.symbols[i].prods[j]].rhs.length; k++) { if (global.symbols[global.productions[global.symbols[i].prods[j]].rhs[k]].kind == SYM.NONTERM) { for (l = 0; l < reachable.length; l++) { if (reachable[l] == global.productions[global.symbols[i].prods[j]].rhs[k]) { break; } } if (l == reachable.length) { stack.push(global.productions[global.symbols[i].prods[j]].rhs[k]); reachable.push(global.productions[global.symbols[i].prods[j]].rhs[k]); } } } } } for (i = 0; i < global.symbols.length; i++) { if (global.symbols[i].kind == SYM.NONTERM) { for (j = 0; j < reachable.length; j++) { if (reachable[j] == i) { break; } } if (j == reachable.length) { log.warn("Unreachable non-terminal \"" + global.symbols[i].label + "\""); } } } }, /** * Checks the {@link jscc.global.states} array for * states with no lookahead information. Logs an error * if any such states are found. */ check_empty_states: function() { for (var i = 0; i < global.states.length; i++) { if (global.states[i].actionrow.length == 0 && global.states[i].def_act == -1) { log.error("No lookaheads in state " + i + ", watch for endless list definitions"); } } } }; return new jscc.integrity(); }));