1 /* 2 * Copyright (C) 2012-2016 DFKI GmbH 3 * Deutsches Forschungszentrum fuer Kuenstliche Intelligenz 4 * German Research Center for Artificial Intelligence 5 * http://www.dfki.de 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the 9 * "Software"), to deal in the Software without restriction, including 10 * without limitation the rights to use, copy, modify, merge, publish, 11 * distribute, sublicense, and/or sell copies of the Software, and to 12 * permit persons to whom the Software is furnished to do so, subject to 13 * the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included 16 * in all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 */ 26 27 /** 28 * @module workers/jscc-compiler 29 */ 30 31 32 importScripts('asyncCompileUtil.js'); 33 34 /////////////// stub for define()/require() ////////////////////////////// 35 // NOTE only single-requires are supported here! (i.e. no lists of required modules) 36 37 var _modules = { 38 _idgen: 1, 39 _customid: '',//<- set custom ID for next loaded module (will be reset after loading) 40 _defined: {}, 41 _get: function(id){ 42 return this._defined[id]; 43 } 44 }; 45 46 define = function(moduleCreateFunc){ 47 var modId; 48 if(_modules._customid){ 49 modId = _modules._customid; 50 _modules._customid = ''; 51 } else { 52 modId = moduleCreateFunc.name? moduleCreateFunc.name : 'mod'+(this._idgen++); 53 } 54 _modules._defined[modId] = moduleCreateFunc(); 55 }; 56 57 require = function(id, cb){ 58 if(cb){ 59 return cb(_modules._get(id)); 60 } 61 return _modules._get(id); 62 }; 63 64 65 /////////////// JS/CC compiler setup ////////////////////////////// 66 67 var jscc; 68 function _init(url){ 69 70 var libUrl = getPath(url) + '.js'; 71 _modules._customid = 'jscc'; 72 importScripts(libUrl);//'../vendor/libs/jscc-amd.js'); 73 74 //set global var that holds JS/CC: 75 jscc = require('jscc'); 76 } 77 78 79 var defaultOptions = { 80 //current there are no specific options for JS/CC 81 }; 82 83 // setup JSCC compiler: 84 85 //setup logger for compile-messages 86 /** 87 * HELPER for creating default logging / error-print functions 88 * 89 * @function 90 * @private 91 * @memberOf JsccGenerator# 92 * 93 * @see mmir.Logging 94 */ 95 function _createCompileLogFunc(log /*Logger*/, level /*String: log-function-name*/, taskId){ 96 return function(){ 97 var args = _makeArray(arguments); 98 log.postMessage({error: args, level: level, id: taskId}); 99 }; 100 } 101 102 function _preparePrintImpl(id){ 103 104 /** 105 * The default logging function for printing compilation errors. 106 * @private 107 * @name set_printError 108 * @function 109 * @memberOf JsccGenerator.jscc# 110 */ 111 jscc.set_printError( _createCompileLogFunc(self, 'error', id)); 112 113 /** 114 * The default logging function for printing compilation warnings. 115 * @private 116 * @name set_printWarning 117 * @function 118 * @memberOf JsccGenerator.jscc# 119 */ 120 jscc.set_printWarning( _createCompileLogFunc(self, 'warn', id)); 121 122 /** 123 * The default logging function for printing compilation information. 124 * @private 125 * @name set_printInfo 126 * @function 127 * @memberOf JsccGenerator.jscc# 128 */ 129 jscc.set_printInfo( _createCompileLogFunc(self, 'info', id)); 130 131 return true; 132 } 133 134 var _getGenerated = function(genMode, dfaTable){ 135 return { 136 head: jscc.get_code_head(), 137 tables: jscc.print_parse_tables(genMode),//jscc.MODE_GEN_JS 138 dfa: jscc.print_dfa_table(dfaTable),//dfa_table 139 terminals: jscc.print_term_actions(), 140 labels: jscc.print_symbol_labels(), 141 actions: jscc.print_actions(), 142 error: jscc.get_error_symbol_id(), 143 eof: jscc.get_eof_symbol_id(), 144 whitespace: jscc.get_whitespace_symbol_id() 145 }; 146 }; 147 148 149 self.onmessage = function(e){ 150 151 switch(e.data.cmd){ 152 case 'init': 153 init(e.data); 154 break; 155 case 'parse': 156 parse(e.data.text, e.data.config, e.data.id); 157 break; 158 } 159 160 }; 161 162 163 function parse(grammarDefinition, config, id){ 164 165 if(!verifyInit(jscc, 'jscc', id)){ 166 return; 167 } 168 169 var options = _getOptions(config); 170 171 var template = config.template; 172 var inputFieldName = config.inputFieldName; 173 174 //setup print-functions (error, warning, info) for this compile-job: 175 _preparePrintImpl(id); 176 177 //set up the JS/CC compiler: 178 var dfa_table = ''; 179 jscc.reset_all( jscc.EXEC_WEB ); 180 181 var hasError = false; 182 var grammarParser; 183 try { 184 jscc.parse_grammar(grammarDefinition); 185 } catch (err){ 186 var msg = 'Error while compiling grammar: ' + (err.stack?err.stack:err); 187 hasError = msg; 188 189 msg = '[INVALID GRAMMAR] ' + msg; 190 grammarParser = 'var msg = '+JSON.stringify(msg)+'; console.error(msg); throw msg;'; 191 } 192 193 if (jscc.getErrors() == 0) { 194 jscc.undef(); 195 jscc.unreachable(); 196 197 if (jscc.getErrors() == 0) { 198 jscc.first(); 199 jscc.print_symbols(); 200 dfa_table = jscc.create_subset(jscc.get_nfa_states()); 201 dfa_table = jscc.minimize_dfa(dfa_table); 202 203 jscc.set_dfa_table(dfa_table);//FIXME: check, if this is really necessary 204 205 jscc.lalr1_parse_table(false); 206 jscc.resetErrors(); 207 } 208 } 209 210 if (jscc.getErrors() > 0 || jscc.getWarnings() > 0){ 211 jscc.get_printError()(//logger.error( 212 // 'JSCC', 'compile', 213 'there occured' 214 + (jscc.getWarnings() > 0? jscc.getWarnings() + ' warning(s)' : '') 215 + (jscc.getErrors() > 0? jscc.getErrors() + ' error(s)' : '') 216 + ' during compilation.' 217 ); 218 } 219 jscc.resetErrors(); 220 jscc.resetWarnings(); 221 222 if( ! hasError){ 223 grammarParser = _getGenerated(options.targetType, dfa_table); 224 } 225 226 self.postMessage({def: grammarParser, isError: hasError, id: id, done: true}); 227 } 228 229