UNPKG

mmir-lib

Version:

MMIR (Mobile Multimodal Interaction and Relay) library

220 lines (176 loc) 5.94 kB
/** * asnyc grammar compiler for JSCC engine * * @module workers/jscc-compiler * * @requires workers/async-compiler-utils * @requires workers/node-utils * @requires workers/require-utils * * @see mmir.env.grammar.AsyncCompiler * @see mmir.env.grammar.JsccAsyncGenerator */ if(typeof self === 'undefined' && typeof process !== 'undefined'){ require('./nodeWorkerThreadsInit'); } typeof WEBPACK_BUILD !== 'undefined' && WEBPACK_BUILD? require('./asyncCompileUtil.js') : importScripts('asyncCompileUtil.js'); if(typeof WEBPACK_BUILD === 'undefined' || !WEBPACK_BUILD){ importScripts('requirejsStubUtil.js'); } /////////////// JS/CC compiler setup ////////////////////////////// var jscc; self._init = function(url, mmirBaseUrl){ if(typeof WEBPACK_BUILD === 'undefined' || !WEBPACK_BUILD){ var libUrl = self.getPath(url, mmirBaseUrl) + '.js'; self._modules._customid = libUrl;//'mmirf/jscc'; try { importScripts(libUrl); //set global var that holds JS/CC: jscc = self.require(libUrl); } catch(err){ var msg = 'jscc ansync compiler (web worker) _init ERROR: failed importScripts("'+libUrl+'") '; console.log(msg, err); self.postMessage({error: msg + err.stack}); } } else { //set global var that holds JS/CC: jscc = require('mmirf/jscc'); } } self.defaultOptions = { //current there are no specific options for JS/CC }; // setup JSCC compiler: //setup logger for compile-messages /** * HELPER for creating default logging / error-print functions * * @function * @private * @memberOf JsccGenerator# * * @see mmir.Logging */ function _createCompileLogFunc(log /*Logger*/, level /*String: log-function-name*/, taskId){ return function(){ var args = self._makeArray(arguments); log.postMessage({message: args, level: level, id: taskId}); }; } function _preparePrintImpl(id){ /** * The default logging function for printing compilation errors. * @private * @name set_printError * @function * @memberOf JsccGenerator.jscc# */ jscc.set_printError( _createCompileLogFunc(self, 'error', id)); /** * The default logging function for printing compilation warnings. * @private * @name set_printWarning * @function * @memberOf JsccGenerator.jscc# */ jscc.set_printWarning( _createCompileLogFunc(self, 'warn', id)); /** * The default logging function for printing compilation information. * @private * @name set_printInfo * @function * @memberOf JsccGenerator.jscc# */ jscc.set_printInfo( _createCompileLogFunc(self, 'info', id)); return true; } var _getGenerated = function(genMode, dfaTable){ return { head: jscc.get_code_head(), tables: jscc.print_parse_tables(genMode),//jscc.MODE_GEN_JS dfa: jscc.print_dfa_table(dfaTable),//dfa_table terminals: jscc.print_term_actions(), labels: jscc.print_symbol_labels(), actions: jscc.print_actions(), error: jscc.get_error_symbol_id(), eof: jscc.get_eof_symbol_id(), whitespace: jscc.get_whitespace_symbol_id() }; }; self.onmessage = function(e){ switch(e.data.cmd){ case 'init': self.init(e.data); break; case 'parse': parse(e.data.text, e.data.config, e.data.id); break; } }; function parse(grammarDefinition, config, id){ if(!self.verifyInit(jscc, 'jscc', id)){ return; } var options = self._getOptions(config); //setup print-functions (error, warning, info) for this compile-job: _preparePrintImpl(id); //set up the JS/CC compiler: var dfa_table = ''; jscc.reset_all( jscc.EXEC_WEB ); jscc.set_debug(/*show errors: */true, /*show warnings: */true, /*hide trace: */false); var hasError = false; var grammarParser; try { jscc.parse_grammar(grammarDefinition, 'grammar ' + options.id); } catch (err){ var msg = 'Error while compiling grammar: ' + (err.stack?err.stack:err); hasError = msg; msg = '[INVALID GRAMMAR] ' + msg + '\n-----------------------------\n Grammar Definition:\n-----------------------------\n' + grammarDefinition; grammarParser = 'var msg = '+JSON.stringify(msg)+'; console.error(msg); return {error: msg, phrase: nl_input_text, engine: "jscc"};'; } var errorCount = jscc.getErrors(); var warnCount = jscc.getWarnings(); if (errorCount == 0) { jscc.undef(); jscc.unreachable(); errorCount = jscc.getErrors(); if (errorCount == 0) { jscc.first(); jscc.print_symbols(); dfa_table = jscc.create_subset(jscc.get_nfa_states()); dfa_table = jscc.minimize_dfa(dfa_table); jscc.set_dfa_table(dfa_table);//FIXME: check, if this is really necessary jscc.lalr1_parse_table(false); } } if (errorCount > 0 || warnCount > 0){ jscc.get_printError()(//logger.error( // 'JSCC', 'compile', 'there occured' + (warnCount > 0? warnCount + ' warning(s)' : '') + (errorCount > 0? errorCount + ' error(s)' : '') + ' during compilation.' ); hasError = errorCount > 0; } if( ! hasError){ grammarParser = _getGenerated(options.targetType, dfa_table); } else { var msg = 'Error'+(errorCount === 1? '': 's')+' parsing grammar ('+errorCount+'):\n ' + jscc.getErrorMessages().join('\n '); if(warnCount > 0){ msg += '\nWarning'+(warnCount === 1? '': 's')+' parsing grammar('+warnCount+'):\n ' + jscc.getWarningMessages().join('\n '); } hasError = msg; msg = '[INVALID GRAMMAR] ' + msg + '\n-----------------------------\n Grammar Definition:\n-----------------------------\n' + grammarDefinition; grammarParser = 'var msg = '+JSON.stringify(msg)+'; console.error(msg); return {error: msg, phrase: nl_input_text, engine: "jscc"};'; } jscc.resetErrors(); jscc.resetWarnings(); self.postMessage({def: grammarParser, isError: hasError, id: id, done: true}); }