jscc-parser
Version:
A LALR(1) Parser Generator for JavaScript written in JavaScript.
1,307 lines (1,250 loc) • 246 kB
JavaScript
/**
* @fileoverview
* @suppress {uselessCode|globalThis}
*/
/*
* Contains type definitions for Closure's benefit. Used as a
* start file when optimizing with requirejs.
*/
"use strict";
/**
* The root namespace. Re-add the const tag after Closure bug #1235 is fixed.
* @namespace
*/
this["jscc"] = {};
//>>excludeStart("jsccNamespacePreDefined", pragmas.jsccNamespacePreDefined);
var jscc = this["jscc"];
//>>excludeEnd("jsccNamespacePreDefined");
//>>includeStart("jsccNamespacePreDefined", pragmas.jsccNamespacePreDefined);
jscc = this["jscc"];
//>>includeEnd("jsccNamespacePreDefined");
/**
* 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;
//>>includeStart("amdclean", pragmas.amdclean);
/**
* @typedef {(function(!string):*|Object)}
*/
//>>includeEnd("amdclean");
//>>excludeStart("amdclean", pragmas.amdclean);
/**
* @typedef {function(!string):*}
*/
//>>excludeEnd("amdclean");
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() {
}
});
//amdclean
/** @suppress {duplicate} */
var util = require("util");
/** @suppress {duplicate} */
var fs = require("fs");
/** @suppress {duplicate} */
var path = require("path");
/**
* @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;
}
};
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() {
//>>excludeStart("closure", pragmas.closure);
var jscc = {};
//>>excludeEnd("closure");
/**
* 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() {
//>>excludeStart("closure", pragmas.closure);
var jscc = {
enums: {}
};
/**
* Identifies the type of an edge in an automation graph.
* @enum {number}
* @memberof jscc.enums
*/
jscc.enums.EDGE = {
FREE: 0,
EPSILON: 1,
CHAR: 2
};
//>>excludeEnd("closure");
/**
* 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) {
//>>excludeStart("closure", pragmas.closure);
var jscc = {
classes: {}
};
var has = /** @type {hasObject} */ (require("../localHas"));
//>>excludeEnd("closure");
var BitSet, tmpBitSet, EDGE = require("../enums/EDGE");
/**
* @suppress {uselessCode}
*/
(function() {
if (has("node")) {
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) {
//>>excludeStart("closure", pragmas.closure);
var jscc = {};
//>>excludeEnd("closure");
var BitSet,
tmpBitSet,
EDGE = require("./enums/EDGE"),
Nfa = /** @type {function(new:jscc.classes.Nfa, ?NfaOptions=)} */ (require("./classes/Nfa"));
//>>excludeStart("closure", pragmas.closure);
var has = /** @type {hasObject} */ (require("./localHas"));
//>>excludeEnd("closure");
/**
* @suppress {uselessCode}
*/
(function() {
if (has("node")) {
tmpBitSet = require("./bitset/BitSet32");
} else {
tmpBitSet = require("./bitset");
}
})();
BitSet = /** @type {function(new:jscc.bitset)} */ (tmpBitSet);
/**
* Module with a class that creates and stores Nfa objects.
* @module {jscc.NFAStates} jscc/nfaStates
* @constructor
*/
jscc.NFAStates = function() {
};
/**
* The inner array of Nfa objects.
* @type {!Array<!jscc.classes.Nfa>}
*/
jscc.NFAStates.prototype.value = [];
/**
* Finds an empty Nfa already in the value array if possible,
* and returns its index. Otherwise, creates a new Nfa object
* and returns its index within the value array.
* @returns {number} The index of the new or recycled Nfa
* object within the value array.
*/
jscc.NFAStates.prototype.create = function() {
var nfa;
var i;
// Use an empty item if available, else create a new one...
for (i = 0; i < this.value.length; i++) {
if (this.value[i].edge === EDGE.FREE) {
break;
}
}
if (i == this.value.length) {
nfa = new Nfa();
this.value.push(nfa);
} else {
nfa = this.value[i];
}
nfa.edge = EDGE.EPSILON;
nfa.ccl = new BitSet();
nfa.accept = -1;
nfa.follow = -1;
nfa.follow2 = -1;
nfa.weight = -1;
return i;
};
return jscc.NFAStates;
}));
(function(root, factory) {
/* istanbul ignore next */
if (typeof define === 'function' && define.amd) {
define('lib/jscc/enums/SYM',factory);
} else if (typeof module === 'object' && module.exports) {
module.exports = factory();
} else {
root.jsccSYM = factory();
}
}(this, function() {
//>>excludeStart("closure", pragmas.closure);
var jscc = {
enums: {}
};
/**
* Identifies a symbol as nonterminating or terminating.
* @enum {number}
* @memberof jscc.enums
*/
jscc.enums.SYM = {
/**
* The symbol is nonterminating.
*/
NONTERM: 0,
/**
* The symbol is terminating.
*/
TERM: 1
};
//>>excludeEnd("closure");
/**
* Module containing SYM enumeration.
* @module jscc/enums/SYM
*/
return jscc.enums.SYM;
}));
(function(root, factory) {
/* istanbul ignore next */
if (typeof define === 'function' && define.amd) {
define('lib/jscc/enums/ASSOC',factory);
} else if (typeof module === 'object' && module.exports) {
module.exports = factory();
} else {
root.jsccASSOC = factory();
}
}(this, function() {
//>>excludeStart("closure", pragmas.closure);
var jscc = {
enums: {}
};
/**
* Indicates the associativity of a symbol.
* @enum {number}
* @memberof jscc.enums
*/
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
};
//>>excludeEnd("closure");
/**
* Module containing ASSOC enumeration.
* @module jscc/enums/ASSOC
*/
return jscc.enums.ASSOC;
}));
(function(root, factory) {
/* istanbul ignore next */
if (typeof define === 'function' && define.amd) {
define('lib/jscc/enums/SPECIAL',factory);
} else if (typeof module === 'object' && module.exports) {
module.exports = factory();
} else {
root.jsccSPECIAL = factory();
}
}(this, function() {
//>>excludeStart("closure", pragmas.closure);
var jscc = {
enums: {}
};
/**
* Identifies a special symbol. Special symbols include
* end-of-file, whitespace, and error symbols. Use
* NONE to indicate a non-special symbol.
* @enum {number}
* @memberof jscc.enums
*/
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
};
//>>excludeEnd("closure");
/**
* Module containing SPECIAL enumeration.
* @module jscc/enums/SPECIAL
*/
return jscc.enums.SPECIAL;
}));
/*
* Universal module definition for the Symbol class module.
*/
(function(root, factory) {
/* istanbul ignore next */
if (typeof define === 'function' && define.amd) {
define('lib/jscc/classes/Symbol',["require", "../enums/SYM", "../enums/ASSOC", "../enums/SPECIAL"], factory);
} else if (typeof module === 'object' && module.exports) {
module.exports = factory(require);
} else {
root.jsccSymbol = factory(function(mod) {
return root["jscc" + mod.split("/").pop()];
});
}
}(this,
/**
* @param {reqParameter} require
* @param {...*} others
* @returns {function(new:jscc.classes.Symbol, SymbolOptions=)}
*/
function(require, others) {
//>>excludeStart("closure", pragmas.closure);
var jscc = {
classes: {}
};
//>>excludeEnd("closure");
var SYM = require("../enums/SYM"),
ASSOC = require("../enums/ASSOC"),
SPECIAL = require("../enums/SPECIAL");
/**
* Creates a new Symbol instance.
* @classdesc Represents a symbol in the grammar.
* @param {SymbolOptions=} o - Optional overrides for default property values.
* @constructor
* @memberof {jscc.classes}
* @const
*/
jscc.classes.Symbol = function(o) {
var p = o || {};
if (typeof p.id === 'number') {
this.id = p.id;
}
if (p.kind === SYM.TERM) {
this.kind = p.kind;
}
if (typeof p.label === 'string') {
this.label = p.label;
}
if (Array.isArray(p.prods)) {
this.prods = /** @type {!Array<number>} */ (p.prods);
}
if (Array.isArray(p.first)) {
this.first = /** @type {!Array<number>} */ (p.first);
}
if (p.associativity === ASSOC.LEFT ||
p.associativity === ASSOC.RIGHT ||
p.associativity === ASSOC.NOASSOC) {
this.associativity = p.associativity;
}
if (typeof p.level === 'number') {
this.level = p.level;
}
if (typeof p.code === 'string') {
this.code = p.code;
}
if (p.special === SPECIAL.EOF ||
p.special === SPECIAL.ERROR ||
p.special === SPECIAL.WHITESPACE) {
this.special = p.special;
}
if (typeof p.nullable === 'boolean') {
this.nullable = p.nullable;
}
if (typeof p.defined === 'boolean') {
this.defined = p.defined;
}
};
/**
* The unique identifier for this symbol. Generally, this value should match the symbol's index within the
* global symbol array.
* @type {!number}
*/
jscc.classes.Symbol.prototype.id = -1;
/**
* Whether the symbol is terminating or nonterminating.
* @type {!jscc.enums.SYM}
*/
jscc.classes.Symbol.prototype.kind = SYM.NONTERM;
/**
* The text of this symbol.
* @type {!string}
*/
jscc.classes.Symbol.prototype.label = "";
/**
* The set of productions associated with this symbol, as identified by
* their id values within the global productions array.
* @type {!Array<number>}
*/
jscc.classes.Symbol.prototype.prods = [];
/**
* The "first" array.
* @type {!Array<number>}
*/
jscc.classes.Symbol.prototype.first = [];
/**
* The associativity of this symbol.
* @type {!jscc.enums.ASSOC}
*/
jscc.classes.Symbol.prototype.associativity = ASSOC.NONE;
/**
* The level of this symbol.
* @type {!number}
*/
jscc.classes.Symbol.prototype.level = 0;
/**
* The code that this symbol produces.
* @type {!string}
*/
jscc.classes.Symbol.prototype.code = "";
/**
* The type of special symbol, if any, that this symbol represents.
* @type {!jscc.enums.SPECIAL}
*/
jscc.classes.Symbol.prototype.special = SPECIAL.NONE;
/**
* Whether this symbol is nullable.
* @type {!boolean}
*/
jscc.classes.Symbol.prototype.nullable = false;
/**
* Whether this symbol is defined.
* @type {!boolean}
*/
jscc.classes.Symbol.prototype.defined = false;
/**
* The module containing the Symbol class.
* @module {function(new:jscc.classes.Symbol, SymbolOptions=)} jscc/classes/Symbol
*/
return jscc.classes.Symbol;
}));
/*
* Universal module definition for Production class.
*/
(function(root, factory) {
/* istanbul ignore next */
if (typeof define === 'function' && define.amd) {
define('lib/jscc/classes/Production',factory);
} else if (typeof module === 'object' && module.exports) {
module.exports = factory();
} else {
root.jsccProduction = factory();
}
}(this, function() {
//>>excludeStart("closure", pragmas.closure);
var jscc = {
classes: {}
};
//>>excludeEnd("closure");
/**
* Creates a new Production instance.
* @classdesc Represents a production created from the grammar.
* @param {ProductionOptions=} o - Overrides for default property values.
* @constructor
* @memberof {jscc.classes}
* @const
*/
jscc.classes.Production = function(o) {
var p = o || {};
if (typeof p.id === 'number') {
this.id = /** @type {number} */ (p.id);
}
if (typeof p.lhs === 'number') {
this.lhs = /** @type {number} */ (p.lhs);
}
if (typeof p.rhs !== 'undefined' && Array.isArray(p.rhs)) {
this.rhs = /** @type {!Array<!number>} */ (p.rhs);
}
if (typeof p.level === 'number') {
this.level = /** @type {number} */ (p.level);
}
if (typeof p.code === 'string') {
this.code = /** @type {string} */ (p.code);
}
};
/**
* The unique identifier of this production, which should
* match its index within the global productions array.
* @type {!number}
*/
jscc.classes.Production.prototype.id = -1;
/**
* The id of the symbol representing the left-hand side of
* this production.
* @type {!number}
*/
jscc.classes.Production.prototype.lhs = -1;
/**
* The id values of the symbols representing the right-hand side
* of this production.
* @type {!Array<!number>}
*/
jscc.classes.Production.prototype.rhs = [];
/**
* The level of this production.
* @type {!number}
*/
jscc.classes.Production.prototype.level = 0;
/**
* The code associated with this production.
* @type {!string}
*/
jscc.classes.Production.prototype.code = "";
/**
* Contains the Production class.
* @module {function(new:jscc.classes.Production, ProductionOptions=)} jscc/classes/Production
*/
return jscc.classes.Production;
}));
(function(root, factory) {
/* istanbul ignore next */
if (typeof define === 'function' && define.amd) {
define('lib/jscc/enums/EXEC',factory);
} else if (typeof module === 'object' && module.exports) {
module.exports = factory();
} else {
root.jsccEXEC = factory();
}
}(this, function() {
//>>excludeStart("closure", pragmas.closure);
var jscc = {
enums: {}
};
/**
* Indicates whether the executable environment is a
* console-based Javascript engine or a web environment.
* @enum {number}
* @memberof jscc.enums
*/
jscc.enums.EXEC = {
/**
* A console-based Javascript engine is in use.
*/
CONSOLE: 0,
/**
* A web-browser-based Javascript engine is in use.
*/
WEB: 1
};
//>>excludeEnd("closure");
/**
* Module containing EXEC enumeration.
* @module jscc/enums/EXEC
*/
return jscc.enums.EXEC;
}));
/*
* Universal module definition for global variables in JS/CC.
*/
(function(root, factory) {
/* istanbul ignore next */
if (typeof define === 'function' && define.amd) {
define('lib/jscc/global',['require', 'text!./template/parser-driver-js.txt', './nfaStates', './classes/Symbol',
'./classes/Production', './enums/SYM',
'./enums/SPECIAL', './enums/EXEC'], factory);
} else if (typeof module === 'object' && module.exports) {
module.exports = factory(require);
} else {
root.jsccglobal =
factory(function(mod) {
var parts = mod.split("/");
var last = parts[parts.length - 1];
if (/js\.txt$/.test(last)) {
return root.jsccDEFAULT_PARSER_DRIVER;
}
return root["jscc" + last];
});
}
}(this,
/**
* @param {reqParameter} require
* @param {...*} others
* @returns {jscc.global}
*/
function(require, others) {
//>>excludeStart("closure", pragmas.closure);
var jscc = {};
var has = /** @type {hasObject} */ (require("./localHas"));
//>>excludeEnd("closure");
var defaultParserDriver,
nfaStates = /** @type {function(new:jscc.NFAStates)} */ (require("./nfaStates")),
Symbol = /** @type {function(new:jscc.classes.Symbol, ?SymbolOptions=)} */ (require("./classes/Symbol")),
Production = /** @type {function(new:jscc.classes.Production)} */ (require("./classes/Production")),
SYM = require("./enums/SYM"),
SPECIAL = require("./enums/SPECIAL"),
EXEC = require("./enums/EXEC");
/**
* @suppress {uselessCode}
*/
(function() {
if (has("node")) {
try {
defaultParserDriver = /** @type {string} */ (require("text!./template/parser-driver-js.txt"));
} catch (e) {
if (typeof fs !== "undefined" && typeof path !== "undefined") {
defaultParserDriver = /** @type {string} */
(fs.readFileSync(path.join(__dirname, "template", "parser-driver-js.txt"), "utf8"));
} else if (typeof require === "function") {
defaultParserDriver = /** @type {string} */
(require("fs")
.readFileSync(require("path").join(__dirname, "template", "parser-driver-js.txt"),
"utf8"));
}
}
} else {
defaultParserDriver = /** @type {string} */ (r