jscc-parser
Version:
A LALR(1) Parser Generator for JavaScript written in JavaScript.
1,232 lines (1,139 loc) • 253 kB
JavaScript
/**
* @fileoverview
* @suppress {globalThis}
*/
/*
* Contains type definitions for Closure's benefit. Used as a
* start file when optimizing with requirejs.
*/
/**
* The root namespace. Re-add the const tag after Closure bug #1235 is fixed.
* @namespace
*/
this["jscc"] = {};
var jscc = this["jscc"];
/**
* The namespace to which enum definitions belong.
* @namespace
*/
jscc["enums"] = {};
/**
* The namespace to which certain classes belong.
* @namespace
*/
jscc["classes"] = {};
jscc.enums = jscc["enums"];
jscc.classes = jscc["classes"];
/*
* To avoid type errors with enums, add the enum module code here. The enum modules
* will simply return the enum objects when the closure pragma is defined. There
* really should be a better solution than this, and maybe there is.
*/
/**
* Indicates the associativity of a symbol.
* @enum {number}
*/
jscc.enums.ASSOC = {
/**
* The associativity has not yet been set.
*/
NONE: 0,
/**
* The symbol is left-associative.
*/
LEFT: 1,
/**
* The symbol is right-associative.
*/
RIGHT: 2,
/**
* The symbol is non-associative.
*/
NOASSOC: 3
};
/**
* Identifies the type of an edge in an automation graph.
* @enum {number}
*/
jscc.enums.EDGE = {
FREE: 0,
EPSILON: 1,
CHAR: 2
};
/**
* Indicates whether the executable environment is a
* console-based Javascript engine or a web environment.
* @enum {number}
*/
jscc.enums.EXEC = {
/**
* A console-based Javascript engine is in use.
*/
CONSOLE: 0,
/**
* A web-browser-based Javascript engine is in use.
*/
WEB: 1
};
/**
* Specifies the minimum logging level.
* @enum {number}
*/
jscc.enums.LOG_LEVEL = {
/**
* Log all messages.
*/
TRACE: 0,
/**
* Log debug messages and higher.
*/
DEBUG: 1,
/**
* Log info messages and higher.
*/
INFO: 2,
/**
* Log warning messages and higher.
*/
WARN: 3,
/**
* Log error and fatal messages.
*/
ERROR: 4,
/**
* Log only fatal messages.
*/
FATAL: 5
};
// Export from Closure, as this enumeration may be used in the
// mainOptions typedef.
jscc.enums.LOG_LEVEL['TRACE'] = jscc.enums.LOG_LEVEL.TRACE;
jscc.enums.LOG_LEVEL['DEBUG'] = jscc.enums.LOG_LEVEL.DEBUG;
jscc.enums.LOG_LEVEL['INFO'] = jscc.enums.LOG_LEVEL.INFO;
jscc.enums.LOG_LEVEL['WARN'] = jscc.enums.LOG_LEVEL.WARN;
jscc.enums.LOG_LEVEL['ERROR'] = jscc.enums.LOG_LEVEL.ERROR;
jscc.enums.LOG_LEVEL['FATAL'] = jscc.enums.LOG_LEVEL.FATAL;
jscc.enums['LOG_LEVEL'] = jscc.enums.LOG_LEVEL;
/**
* Indicates an output mode for the parser.
* @enum {number}
*/
jscc.enums.MODE_GEN = {
/**
* Output is plain text.
*/
TEXT: 0,
/**
* Output is JavaScript code.
*/
JS: 1,
/**
* Output is HTML-formatted.
*/
HTML: 2
};
/**
* Identifies a special symbol. Special symbols include
* end-of-file, whitespace, and error symbols. Use
* NONE to indicate a non-special symbol.
* @enum {number}
*/
jscc.enums.SPECIAL = {
/**
* Identifies a non-special symbol.
*/
NONE: 0,
/**
* Identifies an end-of-file symbol.
*/
EOF: 1,
/**
* Identifies a whitespace symbol.
*/
WHITESPACE: 2,
/**
* Identifies an error symbol.
*/
ERROR: 3
};
/**
* Identifies a symbol as nonterminating or terminating.
* @enum {number}
*/
jscc.enums.SYM = {
/**
* The symbol is nonterminating.
*/
NONTERM: 0,
/**
* The symbol is terminating.
*/
TERM: 1
};
/*
* Some option-override, fictional types.
*/
/**
* @typedef {{id: ?number, kind: ?jscc.enums.SYM, label: ?string, prods: ?Array<number>, first:
* ?Array, associativity: ?jscc.enums.ASSOC, level: ?number, code: ?string, special: ?jscc.enums.SPECIAL,
* defined: ?boolean, "nullable": ?boolean}}
*/
var SymbolOptions;
/**
* @typedef {{id: ?number, lhs: ?number, rhs: ?Array<!number>, level: ?number, code: ?string}}
*/
var ProductionOptions;
/**
* @typedef {{kernel: ?Array<!jscc.classes.Item>, epsilon: ?Array<!jscc.classes.Item>, def_act: ?number, done:
* ?boolean, closed: ?boolean, actionrow: ?Array<!jscc.classes.TableEntry>, gotorow:
* ?Array<!jscc.classes.TableEntry>}}
*/
var StateOptions;
/**
* @typedef {{prod: ?number, dot_offset: ?number, lookahead: ?Array<!number>}}
*/
var ItemOptions;
/**
* @typedef {{edge: ?jscc.enums.EDGE, ccl: ?jscc.bitset, follow: ?number, follow2: ?number, accept: ?number,
* weight: ?number}}
*/
var NfaOptions;
/**
* @typedef {{line: ?Array, nfa_set: ?Array<!number>, accept: ?number, done: ?boolean, group: ?number}}
*/
var DfaOptions;
/**
* @typedef {{out_file: ?string, src_file: ?string, tpl_file: ?string, input: ?(string|function():!string),
* template: ?(string|function():!string), outputCallback: ?function(string):void, dump_nfa: ?boolean,
* dump_dfa: ?boolean, verbose: ?boolean, logLevel: ?(string|jscc.enums.LOG_LEVEL)}}
* @property {?string} out_file - The path of the output file. Defaults to
* the empty string, which means to print to standard output (or the engine's equivalent).
* @property {?string} src_file - The path of the input grammar file.
* Defaults to the empty string, which means to read from standard input (or
* the engine's equivalent).
* @property {?string} tpl_file - The path of the input template file.
* Defaults to the module's default template file, which is intended for generic
* compilation tasks.
* @property {?(string|function():!string)} input - If a string, the contents of the
* input grammar. If a function with no arguments, a function that returns
* the contents of the grammar. When input is specified, src_file is ignored.
* @property {?(string|function():!string)} template - If a string, the contents of the
* template. If a function with no arguments, a function that returns the contents
* of the template. When template is specified, tpl_file is ignored.
* @property {?function(string):void} outputCallback - A function with a parameter
* that will be called with the output. When outputCallback is specified,
* out_file is ignored.
* @property {?boolean} dump_nfa - Whether to output the nondeterministic finite
* automata for debugging purposes. Defaults to false.
* @property {?boolean} dump_dfa - Whether to output the deterministic finite
* automata for debugging purposes. Defaults to false.
* @property {?boolean} verbose - Make debugging output chattier. Defaults to
* false.
* @property {?(string|jscc.enums.LOG_LEVEL)} logLevel - The logging
* level. Can be the name of one of the {@link module:jscc.enums.LOG_LEVEL} values
* or one of the values themselves. Defaults to WARN.
* @property {?boolean} throwIfErrors - Whether to throw an exception before completion
* of the main method if there are any errors.
* @property {?boolean} exitIfErrors - Whether to exit the process with a non-zero exit
* code if there are any errors, provided that the platform permits doing so. Intended
* for use with shell scripts.
*/
var mainOptions;
/**
* @typedef {function(!string):*}
*/
var reqParameter;
/**
* @typedef {function((undefined|string|Array<string>|{deps: (string|Array<string>), callback: (string|Function)}), (string|Function|Array<string>)=, (string|Function)=, (string|boolean)=, boolean=):almondRequire}
*/
var almondRequire;
var almondRequireExtension =
/**
* @lends {almondRequire}
*/
({
/**
* @type {!Object<string, *>}
*/
_defined: {},
/**
* @param {Object<string, *>} cfg
* @returns {almondRequire}
*/
config: function(cfg) {
}
});
/**
* @typedef {string}
*/
var stringWithErrorMessage;
var stringWithErrorMessageExtension =
/**
* @lends {stringWithErrorMessage}
*/
({
/**
* @type {string}
*/
ERROR_MSG: ""
});
/**
* @typedef {function(string):boolean}
*/
var hasObject;
var hasObjectExtension =
/**
* @lends {hasObject}
*/
({
/**
* @param {string} name
* @param {function(...*):boolean} test
* @param {boolean=} now
*/
add: function(name, test, now) {
},
/**
* @param {T} el
* @returns {T}
* @template T
*/
clearElement: function(el) {
},
/**
* @param {string} name
* @param {*} el
* @returns {boolean}
*/
cssprop: function(name, el) {
},
/**
* @param {*} obj
* @param {*=} property
* @returns {boolean}
*/
isHostType: function(obj, property) {
},
/**
* @returns {Object<string, (boolean|stringWithErrorMessage)>}
*/
all: function() {
}
});
/**
* @typedef {{filename: ?(string|undefined), chunkCallback: ?(function(string):void|undefined), endCallback:
* ?(function():void|undefined)}}
* @property {?(string|undefined)} filename - The filename to read. If omitted, read from standard input.
* @property {?(function(string):void|undefined)} chunkCallback - The function to call when an input chunk is read
* asynchronously.
* @property {?(function():void|undefined)} endCallback - The function to call when the asynchronous read operation has
* completed.
*/
var ioOptions;
/**
* @typedef {{text: string, destination: ?(string|undefined), callback: ?(function():void|undefined)}}
* @property {string} text - The text to be written.
* @property {?(string|undefined)} destination - The filename to which to write the text. If omitted, text is written
* to standard output.
* @property {?(function():void|undefined)} callback - A callback to be executed when the asynchronous write operation
* has completed. If omitted, the operation occurs synchronously instead.
*/
var ioWriteOutputOptions;
/**
* Interface for engine-specific IO modules.
* @interface
*/
jscc.io = function() {
};
jscc.io.prototype = {
/**
* Reads input from the specified file or from standard input.
* If chunkCallback and/or endCallback are specified, the operation
* is asynchronous, and the function returns nothing. Otherwise,
* the operation is synchronous, and the function returns a string
* with the contents read from the file or from standard input.
*
* @param {(string|function(string):void|ioOptions)=} options -
* If a string, the filename to read. If an object, has optional filename, chunkCallback, and endCallback
* properties. If a function, the callback function to execute for each chunk read from standard input.
* @returns {(string|void)} When running synchronously, the text read from
* the file or standard input. When running asynchronously, returns nothing.
*/
read_all_input: function(options) {
},
/**
* Reads the template file into which the parser code is inserted.
* If not specified, uses the default driver specified in
* {@link jscc.global.DEFAULT_DRIVER}.
*
* @param {(string|function(string):void|ioOptions)=} options -
* If a string, specifies the template filename. If a function, specifies the callback function to be used
* when reading a file chunk has completed. If an object, specifies either or both. If omitted, causes the
* function to read
* {@link jscc.global.DEFAULT_DRIVER} synchronously.
* @returns {(string|void)} When running synchronously, returns the contents of
* the template file as a string. When running asynchronously, returns
* nothing.
*/
read_template: function(options) {
},
/**
* Writes the provided text to the specified file or to standard output.
*
* @param {(string|ioWriteOutputOptions)} options - When a string, the text
* to be written to standard output. When an object, contains text, destination, and callback properties.
*/
write_output: function(options) {
},
/**
* Writes the provided text to a debugging output, provided that such an output
* exists in the implementation of this interface.
*
* @param {string} text - The text to write to the debugging output.
*/
write_debug: function(text) {
},
/**
* Attempts to exit the entire process with the provided exit code if the
* platform supports doing so. Callers should also ensure that all functions
* exit appropriately if the platform does not support this feature.
*
* @param {number=} exitCode - The exit code to use.
*/
exit: function(exitCode) {
}
};
/**
* Interface for engine-specific logging modules.
* @interface
*/
jscc.log = function() {
};
jscc.log.prototype = {
/**
* Logs a message at the fatal level.
* @param {string} msg - The message to log.
*/
fatal: function(msg) {
},
/**
* Logs a message at the error level.
* @param {string} msg - The message to log.
*/
error: function(msg) {
},
/**
* Logs a message at the warning level.
* @param {string} msg - The message to log.
*/
warn: function(msg) {
},
/**
* Logs a message at the info level.
* @param {string} msg - The message to log.
*/
info: function(msg) {
},
/**
* Logs a message at the debug level.
* @param {string} msg - The message to log.
*/
debug: function(msg) {
},
/**
* Logs a message at the trace level.
* @param {string} msg - The message to log.
*/
trace: function(msg) {
},
/**
* Sets the minimum level to log. This function
* may not have an effect at all times with all
* loggers.
* @param {jscc.enums.LOG_LEVEL} level - The
* minimum level to log.
*/
setLevel: function(level) {
}
};
/**
* Interface definition for bitset implementations.
* @interface
*/
jscc.bitset = function() {
};
jscc.bitset.prototype = {
/**
* Sets the specified bit to true or false.
* @param {!number} bit - The index of the bit to set
* @param {boolean=} state - Whether to set the bit to true or false
* @returns {!boolean} Returns the state parameter for chaining purposes
* @method
*/
set: function(bit, state) {
return false;
},
/**
* Gets the bit at the specified index.
* @param {!number} bit - The index of the bit to get
* @returns {!boolean} Whether the bit is currently true or false
* @method
*/
get: function(bit) {
return false;
},
/**
* Returns the number of true values in the bitset.
* @returns {!number} The number of true values in the bitset
* @method
*/
count: function() {
return 0;
}
};
/**
* @license almond 0.3.2 Copyright jQuery Foundation and other contributors.
* Released under MIT license, http://github.com/requirejs/almond/LICENSE
*/
//Going sloppy to avoid 'use strict' string cost, but strict practices should
//be followed.
/*global setTimeout: false */
/** @type {almondRequire} */
var requirejs;
/** @type {almondRequire} */
var require;
var define;
(function (undef) {
var main, req, makeMap, handlers,
/** @type {!Object<string, *>} */
defined = {},
/** @type {!Object<string, Array>} */
waiting = {},
config = {},
/** @type {!Object<string, boolean>} */
defining = {},
hasOwn = Object.prototype.hasOwnProperty,
aps = [].slice,
jsSuffixRegExp = /\.js$/;
/**
* @param {!Object} obj
* @param {!string} prop
* @returns {!boolean}
*/
function hasProp(obj, prop) {
return hasOwn.call(obj, prop);
}
/**
* Given a relative module name, like ./something, normalize it to
* a real name that can be mapped to a path.
* @param {string} name the relative name
* @param {string} baseName a real name that the name arg is relative
* to.
* @returns {string} normalized name
*/
function normalize(name, baseName) {
var /** @type {Array<string>} */ nameParts, nameSegment, mapValue, foundMap, lastIndex,
foundI, foundStarMap, starI, i, j, part, normalizedBaseParts,
baseParts = /** @type {Array<string>} */ (baseName && baseName.split("/")),
map = config.map,
starMap = (map && map['*']) || {};
//Adjust any relative paths.
if (name) {
nameParts = name.split('/');
lastIndex = nameParts.length - 1;
// If wanting node ID compatibility, strip .js from end
// of IDs. Have to do this here, and not in nameToUrl
// because node allows either .js or non .js to map
// to same file.
if (config.nodeIdCompat && jsSuffixRegExp.test(nameParts[lastIndex])) {
nameParts[lastIndex] = nameParts[lastIndex].replace(jsSuffixRegExp, '');
}
// Starts with a '.' so need the baseName
if (nameParts[0].charAt(0) === '.' && baseParts) {
//Convert baseName to array, and lop off the last part,
//so that . matches that 'directory' and not name of the baseName's
//module. For instance, baseName of 'one/two/three', maps to
//'one/two/three.js', but we want the directory, 'one/two' for
//this normalization.
normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);
nameParts = normalizedBaseParts.concat(nameParts);
}
//start trimDots
for (i = 0; i < nameParts.length; i++) {
part = nameParts[i];
if (part === '.') {
nameParts.splice(i, 1);
i -= 1;
} else if (part === '..') {
// If at the start, or previous value is still ..,
// keep them so that when converted to a path it may
// still work when converted to a path, even though
// as an ID it is less than ideal. In larger point
// releases, may be better to just kick out an error.
if (!((i === 1 && nameParts[2] === '..') || nameParts[i - 1] === '..') && i > 0) {
nameParts.splice(i - 1, 2);
i -= 2;
}
}
}
//end trimDots
name = nameParts.join('/');
nameParts = null;
}
//Apply map config if available.
if ((baseParts || starMap) && map) {
nameParts = name.split('/');
for (i = nameParts.length; i > 0; i -= 1) {
nameSegment = nameParts.slice(0, i).join("/");
if (baseParts) {
//Find the longest baseName segment match in the config.
//So, do joins on the biggest to smallest lengths of baseParts.
for (j = baseParts.length; j > 0; j -= 1) {
mapValue = map[baseParts.slice(0, j).join('/')];
//baseName segment has config, find if it has one for
//this name.
if (mapValue) {
mapValue = mapValue[nameSegment];
if (mapValue) {
//Match, update name to the new value.
foundMap = mapValue;
foundI = i;
break;
}
}
}
}
if (foundMap) {
break;
}
//Check for a star map match, but just hold on to it,
//if there is a shorter segment match later in a matching
//config, then favor over this star map.
if (!foundStarMap && starMap && starMap[nameSegment]) {
foundStarMap = starMap[nameSegment];
starI = i;
}
}
if (!foundMap && foundStarMap) {
foundMap = foundStarMap;
foundI = starI;
}
if (foundMap) {
nameParts.splice(0, foundI, foundMap);
name = nameParts.join('/');
}
}
return name;
}
/**
* @param {(string|Array<string>|undefined)} relName
* @param {boolean=} forceSync
* @returns {Function}
*/
function makeRequire(relName, forceSync) {
return function () {
//A version of a require function that passes a moduleName
//value for items that may need to
//look up paths relative to the moduleName
var args = aps.call(arguments, 0);
//If first arg is not require('string'), and there is only
//one arg, it is the array form without a callback. Insert
//a null so that the following concat is correct.
if (typeof args[0] !== 'string' && args.length === 1) {
args.push(null);
}
return req.apply(undef, args.concat([relName, forceSync]));
};
}
/**
* @param {string} relName
* @returns {function(string):string}
*/
function makeNormalize(relName) {
return function (name) {
return normalize(name, relName);
};
}
/**
* @param {string} depName
* @returns {function(*)}
*/
function makeLoad(depName) {
return function (value) {
defined[depName] = value;
};
}
/**
* @param {!string} name
* @returns {*}
*/
function callDep(name) {
if (hasProp(waiting, name)) {
var args = waiting[name];
delete waiting[name];
defining[name] = true;
main.apply(undef, args);
}
if (!hasProp(defined, name) && !hasProp(defining, name)) {
throw new Error('No ' + name);
}
return defined[name];
}
//Turns a plugin!resource to [plugin, resource]
//with the plugin being undefined if the name
//did not have a plugin prefix.
/**
* @param {string} name
* @returns {Array<(string|undefined)>}
*/
function splitPrefix(name) {
var prefix,
index = name ? name.indexOf('!') : -1;
if (index > -1) {
prefix = name.substring(0, index);
name = name.substring(index + 1, name.length);
}
return [prefix, name];
}
/**
* Makes a name map, normalizing the name, and using a plugin
* for normalization if necessary. Grabs a ref to plugin
* too, as an optimization.
* @param {string} name
* @param {string} relName
* @returns {{f: string, n: string, pr: (string|undefined), p: *}}
*/
makeMap = function (name, relName) {
var plugin,
parts = splitPrefix(name),
prefix = parts[0];
name = /** @type {string} */ (parts[1]);
if (prefix) {
prefix = normalize(prefix, relName);
plugin = callDep(prefix);
}
//Normalize according
if (prefix) {
if (plugin && plugin.normalize) {
name = (/** @type {{normalize: function(string, function(string):string):string}} */ (plugin)).normalize(name, makeNormalize(relName));
} else {
name = normalize(name, relName);
}
} else {
name = normalize(name, relName);
parts = splitPrefix(name);
prefix = parts[0];
name = /** @type {string} */ (parts[1]);
if (prefix) {
plugin = callDep(prefix);
}
}
//Using ridiculous property names for space reasons
return {
f: prefix ? prefix + '!' + name : name, //fullName
n: name,
pr: prefix,
p: plugin
};
};
/**
* @param {string} name
* @returns {function():Object}
*/
function makeConfig(name) {
return function () {
return (config && config.config && config.config[name]) || {};
};
}
handlers = {
require: function (name) {
return makeRequire(name);
},
exports: function (name) {
var e = defined[name];
if (typeof e !== 'undefined') {
return e;
} else {
return (defined[name] = {});
}
},
module: function (name) {
return {
id: name,
uri: '',
exports: defined[name],
config: makeConfig(name)
};
}
};
/**
* @param {(string|undefined)} name
* @param {(Array<string>|undefined)} deps
* @param {Function=} callback
* @param {?string=} relName
*/
main = function (name, deps, callback, relName) {
var cjsModule, depName, ret, map, i,
args = [],
callbackType = typeof callback,
usingExports;
//Use name if no relName
relName = /** @type {string} */ (relName || name);
//Call the callback to define the module, if necessary.
if (callbackType === 'undefined' || callbackType === 'function') {
//Pull out the defined dependencies and pass the ordered
//values to the callback.
//Default to [require, exports, module] if no deps
deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;
for (i = 0; i < deps.length; i += 1) {
map = makeMap(deps[i], relName);
depName = map.f;
//Fast path CommonJS standard dependencies.
if (depName === "require") {
args[i] = handlers.require(name);
} else if (depName === "exports") {
//CommonJS module spec 1.1
args[i] = handlers.exports(name);
usingExports = true;
} else if (depName === "module") {
//CommonJS module spec 1.1
cjsModule = args[i] = handlers.module(name);
} else if (hasProp(defined, depName) ||
hasProp(waiting, depName) ||
hasProp(defining, depName)) {
args[i] = callDep(depName);
} else if (map.p) {
map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});
args[i] = defined[depName];
} else {
throw new Error(name + ' missing ' + depName);
}
}
ret = callback ? callback.apply(defined[/** @type {string} */ (name)], args) : undefined;
if (name) {
//If setting exports via "module" is in play,
//favor that over return value and exports. After that,
//favor a non-undefined return value over exports use.
if (cjsModule && cjsModule.exports !== undef &&
cjsModule.exports !== defined[name]) {
defined[name] = cjsModule.exports;
} else if (ret !== undef || !usingExports) {
//Use the return value from the function.
defined[name] = ret;
}
}
} else if (name) {
//May just be an object definition for the module. Only
//worry about defining if have a module name.
defined[name] = callback;
}
};
requirejs = require = req = /** @type {almondRequire} */ (function (deps, callback, relName, forceSync, alt) {
if (typeof deps === "string") {
if (handlers[deps]) {
//callback in this case is really relName
return handlers[deps](/** string */ (callback));
}
//Just return the module wanted. In this scenario, the
//deps arg is the module name, and second arg (if passed)
//is just the relName.
//Normalize module name, if it contains . or ..
return callDep(makeMap(deps, /** @type {string} */ (callback)).f);
}
if (!deps.splice) {
//deps is a config object, not an array.
config = deps;
if (config.deps) {
req(config.deps, config.callback);
}
if (!callback) {
return;
}
if (callback.splice) {
//callback is an array, which means it is a dependency list.
//Adjust args if there are dependencies
deps = /** @type {Array<string>} */ (callback);
callback = relName;
relName = null;
} else {
deps = undef;
}
}
//Support require(['a'])
callback = /** @type {!Function} */ (callback || function () {});
//If relName is a function, it is an errback handler,
//so remove it.
if (typeof relName === 'function') {
relName = /** @type {string} */ (forceSync);
forceSync = alt;
}
//Simulate async callback;
if (forceSync) {
main(undef, /** @type {(Array<string>|undefined)} */ (deps), callback, /** @type {(string|undefined)} */ (relName));
} else {
//Using a non-zero value because of concern for what old browsers
//do, and latest browsers "upgrade" to 4 if lower value is used:
//http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:
//If want a value immediately, use require('id') instead -- something
//that works in almond on the global level, but not guaranteed and
//unlikely to work in other AMD implementations.
setTimeout(function () {
main(undef, /** @type {(Array<string>|undefined)} */ (deps), /** @type {!Function} */ (callback), /** @type {(string|undefined)} */ (relName));
}, 4);
}
return req;
});
/**
* Just drops the config on the floor, but returns req in case
* the config return value is used.
*/
req.config = function (cfg) {
return req(cfg);
};
/**
* Expose module registry for debugging and tooling
*/
requirejs._defined = defined;
/**
* @param {!string} name
* @param {!(Array<string>|Function)} deps
* @param {(Function)=} callback
*/
define = function (name, deps, callback) {
if (typeof name !== 'string') {
throw new Error('See almond README: incorrect module build, no module name');
}
//This module may not have dependencies
if (!deps.splice) {
//deps is not an array, so probably means
//an object literal or factory function for
//the value. Adjust args.
callback = /** @type {Function} */ (deps);
deps = [];
}
if (!hasProp(defined, name) && !hasProp(waiting, name)) {
waiting[name] = [name, deps, callback];
}
};
define.amd = {
jQuery: true
};
}(undefined));
define("bin/almond", function(){});
define('text',{load: function(id){throw new Error("Dynamic load not allowed: " + id);}});
define('text!lib/jscc/template/parser-driver-js.txt',[],function () { return '/*\r\n\tThis is the general, platform-independent part of every parser driver;\r\n\tInput-/Output and Feature-Functions are done by the particular drivers\r\n\tcreated for the particular platform.\r\n*/\r\n##HEADER##\r\nvar __parse=(function(/** number */ eof, /** number */ whitespace, /** number */ error_token){\r\n\t\r\n/// there was "continue" in code, we must to replace it\r\nvar Continue = function(){throw Continue;};\r\n\r\n\t/**\r\n\t * @template T\r\n\t * @param {T} value\r\n\t * @constructor\r\n\t * @extends {Error}\r\n */\r\n\tvar ReturnValue = function(value) {\r\n\t\tError.call(this);\r\n\t\tthis._value = value;\r\n\t};\r\n\tReturnValue.prototype = Object.create(Error.prototype);\r\n\tReturnValue.prototype.constructor = ReturnValue;\r\n\t/**\r\n\t * @type {T}\r\n\t * @private\r\n */\r\n\tReturnValue.prototype._value = null;\r\n\t/**\r\n\t * @returns {T}\r\n */\r\n\tReturnValue.prototype.valueOf = function() {\r\n\t\treturn this._value;\r\n\t};\r\n\r\n\t///can return value from any place of callback\r\n\tfunction Return(value){\r\n\t\tthrow new ReturnValue(value);\r\n\t}\r\n\r\n\tvar TERMINAL_ACTIONS = (function(){\r\n\t\tfunction emptyFn(PCB){return PCB.att;}\r\n\t\tvar actions = ##TERMINAL_ACTIONS##\r\n\t\treturn function(/** @type {!PcbClass} */ PCB, match){\r\n\t\t\ttry{\r\n\t\t\t\treturn (actions[match] || emptyFn)(PCB);\r\n\t\t\t}catch(e){\r\n\t\t\t\tif(e instanceof ReturnValue)return e.valueOf();\r\n\t\t\t\tif(e == Continue)return Continue;\r\n\t\t\t\tthrow e;\r\n\t\t\t}\r\n\t\t}\r\n\t})();\r\n\t/**\r\n\t * @constructor\r\n */\r\n\tvar DfaLex = function() {\r\n\t\tthis._dfaData = ##DFA##;\r\n\t};\r\n\t/**\r\n\t * @type {!Array<!{line: !Array, accept: !number}>}\r\n\t * @private\r\n */\r\n\tDfaLex.prototype._dfaData = [];\r\n\t/**\r\n\t * @type {number}\r\n */\r\n\tDfaLex.prototype.match_pos = 0;\r\n\t/**\r\n\t * @type {?number}\r\n */\r\n\tDfaLex.prototype.state = 0;\r\n\t/**\r\n\t * @type {?number}\r\n */\r\n\tDfaLex.prototype.match = null;\r\n\t/**\r\n\t * @param {number} chr\r\n\t * @param {number} pos\r\n */\r\n\tDfaLex.prototype.exec = function(chr, pos) {\r\n\t\tif (this.state !== null) {\r\n\t\t if ((typeof this.state !== "number") || this.state >= this._dfaData.length) {\r\n\t\t this.state = null;\r\n\t\t throw new Error("Invalid value for DfaLex.state at chr " + chr + " and pos " + pos);\r\n\t\t }\r\n\t\t\tvar line = this._dfaData[this.state].line;\r\n\t\t\tif (typeof line === "undefined" || line === null) {\r\n\t\t\t var badState = this.state;\r\n\t\t\t this.state = null;\r\n\t\t\t throw new Error("At chr " + chr + " and pos " + pos +\r\n\t\t\t ", DfaLex._dfaData[" + badState +\r\n\t\t\t "] appears to exist, but its line property is " +\r\n\t\t\t (typeof line === "undefined" ? "undefined." : "null."));\r\n\t\t\t}\r\n\t\t\tvar p, st;\r\n\t\t\tfor (p = 1 << 8, st = line; p; p >>= 1) {\r\n\t\t\t\tif ((chr & p) !== 0) {\r\n\t\t\t\t\tst = st[1];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tst = st[0];\r\n\t\t\t\t}\r\n\t\t\t\tif (typeof st === "undefined") {\r\n\t\t\t\t st = null;\r\n\t\t\t\t}\r\n\t\t\t\tif (st === null)break;\r\n\t\t\t\tif (Array.isArray(st))continue;\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tvar ac = this._dfaData[this.state].accept;\r\n\t\t\tthis.state = /** @type {?number} */ (st);\r\n\t\t\tif (ac !== -1) {\r\n\t\t\t\tthis.match = /** @type{number} */ (ac);\r\n\t\t\t\tthis.match_pos = pos;\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n##TABLES##\r\n##LABELS##\r\n\tvar ACTIONS = (function(){\r\n\t\tvar PCB = {};\r\n\t\tvar actions = ##ACTIONS##;\r\n\t\treturn function (/** number */ act, /** Array<*> */ vstack, /** !PcbClass */ pcb){\r\n\t\t\ttry{\r\n\t\t\t\tPCB = pcb;\r\n\t\t\t\treturn actions[act].apply(null,vstack);\r\n\t\t\t}catch(e){\r\n\t\t\t\tif(e instanceof ReturnValue)return e.valueOf();\r\n\t\t\t\tthrow e;\r\n\t\t\t}\r\n\t\t}\r\n\t})();\r\n\r\n\t/**\r\n\t * @param {number} top\r\n\t * @param {?number} la\r\n\t * @returns {?number}\r\n */\r\n\tfunction get_act(top, la){\t\r\n\t\tfor(var i = 0; i < act_tab[top].length; i+=2)\r\n\t\t\tif(act_tab[top][i] === la)\r\n\t\t\t\treturn act_tab[top][i+1];\r\n\t\treturn null;\r\n\t}\r\n\tfunction get_goto(top, pop){\t\r\n\t\tfor(var i = 0; i < goto_tab[top].length; i+=2)\r\n\t\t\tif(goto_tab[top][i] === pop)\r\n\t\t\t\treturn goto_tab[top][i+1];\r\n\t\treturn null;\r\n\t}\r\n\r\n\t/**\r\n\t * @param {!string} src\r\n\t * @constructor\r\n */\r\n\tvar PcbClass = function(src) {\r\n\t\tthis.src = src;\r\n\t};\r\n\t/**\r\n\t * @type {number}\r\n */\r\n\tPcbClass.prototype.line = 1;\r\n\t/**\r\n\t * @type {number}\r\n */\r\n\tPcbClass.prototype.column = 1;\r\n\t/**\r\n\t * @type {number}\r\n */\r\n\tPcbClass.prototype.offset = 0;\r\n\t/**\r\n\t * @type {number}\r\n */\r\n\tPcbClass.prototype.error_step = 0;\r\n\t/**\r\n\t * @type {string}\r\n */\r\n\tPcbClass.prototype.src = "";\r\n\t/**\r\n\t * @type {string}\r\n */\r\n\tPcbClass.prototype.att = "";\r\n\t/**\r\n\t * @type {?number}\r\n */\r\n\tPcbClass.prototype.la = null;\r\n\t/**\r\n\t * @type {?number}\r\n */\r\n\tPcbClass.prototype.act = null;\r\n\t/**\r\n\t * @returns {?number}\r\n */\r\n\tPcbClass.prototype.lex = function() {\r\n var /** number */ start, /** number */ pos, /** number */ chr, actionResult;\r\n\t\tvar dfa = new DfaLex();\r\n\t\tvar loop = true;\r\n\t\twhile(loop){\r\n\t\t\tdfa.match_pos = 0;\r\n\t\t\tpos = this.offset + 1;\r\n\t\t\tdo{\r\n\t\t\t\tpos--;\r\n\t\t\t\tdfa.state = 0;\r\n\t\t\t\tdfa.match = null;\r\n\t\t\t\tstart = pos;\r\n\t\t\t\tif(this.src.length <= start) {\r\n\t\t\t\t\tthis.la = eof;\r\n\t\t\t\t\treturn eof;\r\n\t\t\t\t}\r\n\t\t\t\tdo{\r\n\t\t\t\t\tchr = this.src.charCodeAt(pos);\r\n\t\t\t\t\tdfa.exec(chr,pos);\r\n\t\t\t\t\tif(dfa.state !== null)\r\n\t\t\t\t\t\tthis.accountChar(chr);\r\n\t\t\t\t\tpos++;\r\n\t\t\t\t}while(dfa.state !== null);\r\n\t\t\t}while(whitespace > -1 && dfa.match === whitespace);\r\n\t\t\tif(dfa.match !== null){\r\n\t\t\t\tthis.att = this.src.slice(start, dfa.match_pos);\r\n\t\t\t\tthis.offset = dfa.match_pos;\r\n\t\t\t\tactionResult = TERMINAL_ACTIONS(this,dfa.match);\r\n\t\t\t\tif(dfa.state !== null)\r\n\t\t\t\t\tthis.accountChar(chr);\r\n\t\t\t\tif(actionResult === Continue)\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\tthis.att = actionResult;\r\n\t\t\t}else {\r\n\t\t\t\tthis.att = "";\r\n\t\t\t}\r\n\t\t\tloop = false;\r\n\t\t}\r\n\t\tthis.la = dfa.match;\r\n\t\treturn this.la;\r\n\t};\r\n\t/**\r\n\t * @param {number} chr\r\n */\r\n PcbClass.prototype.accountChar = function(chr) {\r\n\t\tif( chr === 10 ){\r\n\t\t\tthis.line++;\r\n\t\t\tthis.column = 0;\r\n\t\t}\r\n\t\tthis.column++;\r\n\t};\r\n\tfunction parse(/** string */ src, err_off, err_la){\r\n\t\t/**\r\n\t\t * @type {!Array<number>}\r\n */\r\n\t\tvar\t\tsstack\t\t\t= [0];\r\n\t\t/**\r\n\t\t * @type {!Array<*>}\r\n */\r\n\t\tvar\t\tvstack\t\t\t= [0];\r\n\t\t/**\r\n\t\t * @type {number}\r\n */\r\n\t\tvar \terr_cnt\t\t\t= 0;\r\n\t\t/**\r\n\t\t * @type {*}\r\n\t\t */\r\n\t\tvar\t\trval;\r\n\t\t/**\r\n\t\t * @type {?number}\r\n\t\t */\r\n\t\tvar\t\tact;\r\n\t\t/**\r\n\t\t * @type {number}\r\n\t\t */\r\n\t\tvar i = 0;\r\n\r\n\t\tvar PCB\t= new PcbClass(src);\r\n\t\terr_off\t= err_off || [];\r\n\t\terr_la = err_la || [];\r\n\t\tPCB.lex();\r\n\t\twhile(true){\r\n\t\t\tPCB.act = get_act(sstack[0],PCB.la);\r\n\t\t\tif(PCB.act === null && defact_tab[sstack[0]] >= 0)\r\n\t\t\t\tPCB.act = -defact_tab[sstack[0]];\r\n\t\t\tif(PCB.act === null){//Parse error? Try to recover!\r\n\t\t\t\t//Report errors only when error_step is 0, and this is not a\r\n\t\t\t\t//subsequent error from a previous parse\r\n\t\t\t\tif(PCB.error_step === 0){\r\n\t\t\t\t\terr_cnt++;\r\n\t\t\t\t\terr_off.unshift(PCB.offset - PCB.att.length);\r\n\t\t\t\t\terr_la.unshift([]);\r\n\t\t\t\t\tfor(i = 0; i < act_tab[sstack[0]].length; i+=2)\r\n\t\t\t\t\t\terr_la[0].push(labels[act_tab[sstack[0]][i]]);\r\n\t\t\t\t}\r\n\t\t\t\t//Perform error recovery\t\t\t\r\n\t\t\t\twhile(sstack.length > 1 && PCB.act === null){\r\n\t\t\t\t\tsstack.shift();\r\n\t\t\t\t\tvstack.shift();\r\n\t\t\t\t\t//Try to shift on error token\r\n\t\t\t\t\tPCB.act = get_act(sstack[0],PCB.la);\r\n\t\t\t\t\tif(PCB.act === error_token){\r\n\t\t\t\t\t\tsstack.unshift(PCB.act);\r\n\t\t\t\t\t\tvstack.unshift("");\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t//Is it better to leave the parser now?\r\n\t\t\t\tif(sstack.length > 1 && PCB.act !== null){\r\n\t\t\t\t\t//Ok, now try to shift on the next tokens\r\n\t\t\t\t\twhile(PCB.la !== eof){\r\n\t\t\t\t\t\tPCB.act = act_tab[sstack[0]][i+1];\r\n\t\t\t\t\t\tif(PCB.act != null)break;\r\n\t\t\t\t\t\twhile(PCB.lex() != null)PCB.offset++;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif(PCB.act === null || PCB.la === eof){\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t\t//Try to parse the next three tokens successfully...\r\n\t\t\t\tPCB.error_step = 3;\r\n\t\t\t}\r\n\t\t\tif(PCB.act > 0){//Shift\r\n\t\t\t\t//Parse tree generation\r\n\t\t\t\tsstack.unshift(PCB.act);\r\n\t\t\t\tvstack.unshift(PCB.att);\r\n\t\t\t\tPCB.lex();\r\n\t\t\t\t//Successfull shift and right beyond error recovery?\r\n\t\t\t\tif(PCB.error_step > 0)\r\n\t\t\t\t\tPCB.error_step--;\r\n\t\t\t}else{\t//Reduce\t\r\n\t\t\t\tact = -PCB.act;\r\n\t\t\t\t//vstack.unshift(vstack);\r\n\t\t\t\trval = ACTIONS(act,vstack,PCB);\r\n\t\t\t\t//vstack.shift();\r\n\t\t\t\tsstack.splice(0,pop_tab[act][1]);\r\n\t\t\t\tvstack.splice(0,pop_tab[act][1]);\r\n\t\t\t\t\r\n\t\t\t\tPCB.act = get_goto(sstack[0],pop_tab[act][0]);\r\n\t\t\t\t//Do some parse tree construction if desired\r\n\t\t\t\t//Goal symbol match?\r\n\t\t\t\tif(act === 0) break; //Don\'t use PCB.act here!\r\n\t\t\t\r\n\t\t\t\t//...and push it!\r\n\t\t\t\tsstack.unshift(PCB.act);\r\n\t\t\t\tvstack.unshift(rval);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn err_cnt;\r\n\t}\r\n\treturn parse;\r\n})(##EOF##,##WHITESPACE##,##ERROR_TOKEN##);\r\n\r\n##FOOTER##\r\n';});
/*
* Universal module definition for a bitset implementation backed by
* integer bitmasks.
*/
(function(root, factory) {
/* istanbul ignore next */
if (typeof define === 'function' && define.amd) {
define('lib/jscc/bitset/BitSet32',factory);
} else if (typeof module === 'object' && module.exports) {
module.exports = factory();
} else {
root.jsccbitset = factory();
}
}(this, function() {
/**
* Creates a new BitSet32 object.
* @classdesc A bitset implementation backed by integer bitmasks.
* @implements {jscc.bitset}
* @constructor
*/
jscc.BitSet32 = function() {
var that = this;
/**
* @private
* @type {!Array<number>}
*/
this._data = [];
/**
* @inheritDoc
* @param {!number} bit
* @param {boolean=} state
* @returns {!boolean}
*/
this.set = function(bit, state) {
state = !!state;
that._data[bit >> 5] =
(state ? (that._data[bit >> 5] | (1 << (bit & 31))) : (that._data[bit >> 5] & ~(1 << (bit & 31))));
return state;
};
/**
* @inheritDoc
* @param {!number} bit
* @returns {!boolean}
*/
this.get = function(bit) {
return ((that._data[bit >> 5] & (1 << (bit & 31))) != 0);
};
/**
* @inheritDoc
* @returns {!number}
*/
this.count = function() {
var i, l, c = 0;
for (i = 0, l = that._data.length * 32; i < l; i++) {
if (that.get(i)) {
c++;
}
}
return c;
};
};
/**
* Module containing BitSet32 implementation. Returns a factory
* function to make Closure slightly happier elsewhere.
* @module {function(new:jscc.BitSet32)} jscc/bitset/BitSet32
*/
return jscc.BitSet32;
}));
(function(root, factory) {
/* istanbul ignore next */
if (typeof define === 'function' && define.amd) {
define('lib/jscc/enums/EDGE',factory);
} else if (typeof module === 'object' && module.exports) {
module.exports = factory();
} else {
root.jsccEDGE = factory();
}
}(this, function() {
/**
* Module containing EDGE enumeration.
* @module jscc/enums/EDGE
*/
return jscc.enums.EDGE;
}));
/*
* Universal module definition for module containing the Nfa class.
*/
(function(root, factory) {
/* istanbul ignore next */
if (typeof define === 'function' && define.amd) {
define('lib/jscc/classes/Nfa',['require', '../enums/EDGE', '../bitset'], factory);
} else if (typeof module === 'object' && module.exports) {
module.exports = factory(require);
} else {
root.jsccNfa = factory(function(mod) {
return root["jscc" + mod.split("/").pop()];
});
}
}(this,
/**
* @param {reqParameter} require
* @param {...*} others
* @returns {function(new:jscc.classes.Nfa, NfaOptions=)}
*/
function(require, others) {
var BitSet, tmpBitSet, EDGE = require("../enums/EDGE");
/**
* @suppress {uselessCode}
*/
(function() {
if (false) {
tmpBitSet = require("../bitset/BitSet32");
} else {
tmpBitSet = require("../bitset");
}
})();
BitSet = /** @type {function(new:jscc.bitset)} */ (tmpBitSet);
/**
* Creates a new Nfa instance.
* @classdesc Represents a state in a nondeterministic finite automata.
* @param {NfaOptions=} o - Optional overrides for default property values.
* @constructor
* @const
*/
jscc.classes.Nfa = function(o) {
var p = o || {};
if (p.edge === EDGE.CHAR || p.edge === EDGE.FREE) {
this.edge = /** @type {!jscc.enums.EDGE} */ (p.edge);
}
if (typeof p.ccl === 'object' && p.ccl.hasOwnProperty("get") && p.ccl.hasOwnProperty("set") &&
p.ccl.hasOwnProperty("count")) {
this.ccl = /** @type {!jscc.bitset} */ (p.ccl);
} else {
this.ccl = new BitSet();
}
if (typeof p.follow === 'number') {
this.follow = /** @type {!number} */ (p.follow);
}
if (typeof p.follow2 === 'number') {
this.follow2 = /** @type {!number} */ (p.follow2);
}
if (typeof p.accept === 'number') {
this.accept = /** @type {!number} */ (p.accept);
}
if (typeof p.weight === 'number') {
this.weight = /** @type {!number} */ (p.weight);
}
};
/**
* The type of edge in this NFA state.
* @type {!jscc.enums.EDGE}
*/
jscc.classes.Nfa.prototype.edge = EDGE.EPSILON;
/**
* The bitset for this NFA state.
* @type {!jscc.bitset}
*/
jscc.classes.Nfa.prototype.ccl = new BitSet();
/**
* Index of an immediately-following state.
* @type {!number}
*/
jscc.classes.Nfa.prototype.follow = -1;
/**
* Index of a second following state.
* @type {!number}
*/
jscc.classes.Nfa.prototype.follow2 = -1;
/**
* Index of an accepting state.
* @type {!number}
*/
jscc.classes.Nfa.prototype.accept = -1;
/**
* The weight of this particular state.
* @type {!number}
*/
jscc.classes.Nfa.prototype.weight = -1;
/**
* The module containing the Nfa class.
* @module jscc/classes/Nfa
*/
return jscc.classes.Nfa;
}));
/*
* Universal module definition for NFAStates (previously in global.js).
*/
(function(root, factory) {
/* istanbul ignore next */
if (typeof define === 'function' && define.amd) {
define('lib/jscc/nfaStates',['require', './bitset', './enums/EDGE', './classes/Nfa'], factory);
} else if (typeof module === 'object' && module.exports) {
module.exports = factory(require);
} else {
root.jsccnfaStates = factory(function(mod) {
return root["jscc" + mod.split("/").pop()];
});
}
}(this,
/**
* @param {reqParameter} require
* @param {...*} others
* @returns {function(new:jscc.NFAStates)}
*/
function(require, others) {
var BitSet,
tmpBitSet,
EDGE = require("./enums/EDGE"),
Nfa = /** @type {function(new:jscc.classes.Nfa, ?NfaOptions=)} */ (require("./classes/Nfa"));
/**
* @suppress {uselessCode}
*/
(function() {
if (false) {
tmpBitSet = r