1 2 3 define(['constants', 'pegjsGen', 'asyncGen', 'jquery'], 4 /** 5 * Asynchronous generator for executable language-grammars (i.e. converted JSON grammars). 6 * 7 * <p> 8 * This generator uses PEG.js for compiling the JSON grammar. 9 * 10 * <p> 11 * Usage of this compile is the same as for synchronously working PegJsGenerator. 12 * 13 * @see PegJsGenerator 14 * 15 * @class 16 * @constant 17 * @public 18 * @name PegJsAsyncGenerator 19 * @memberOf mmir.env.grammar 20 * 21 * @requires PegJsGenerator 22 * @requires jQuery.extend 23 */ 24 function(constants, pegjsGen, asyncGen, $){ 25 26 /** 27 * Counter for generating IDs for compile-jobs that 28 * are sent to the WebWorker 29 * 30 * @private 31 * @memberOf PegJsAsyncGenerator# 32 */ 33 var _taskId = 1; 34 35 /** 36 * WebWorker instance for compiling parser asynchronously 37 * 38 * @private 39 * @memberOf PegJsAsyncGenerator# 40 */ 41 var asyncCompiler = asyncGen.createWorker(pegjsGen.engineId); 42 43 /** 44 * printError function reference for compile-errors 45 * 46 * @private 47 * @memberOf PegJsAsyncGenerator# 48 */ 49 var printError = pegjsGen.printError; 50 51 52 ////////////////////init async compiler/thread ///////////////////////// 53 54 asyncCompiler._onerror = printError; 55 56 //setup async init-signaling: 57 var initDef = $.Deferred(); 58 var initMsg = asyncCompiler.prepareOnInit(pegjsGen, initDef, require); 59 asyncCompiler.postMessage(initMsg); 60 61 62 /** 63 * Exported (public) functions for the PEG.js grammar-engine. 64 * @public 65 * @type GrammarGenerator 66 * @memberOf PegJsAsyncGenerator# 67 */ 68 var pegjsAsyncGen = { 69 /** @scope PegJsAsyncGenerator.prototype */ 70 71 /** 72 * @see PegJsAsyncGenerator#init 73 * @memberOf PegJsAsyncGenerator.prototype 74 */ 75 init: function(callback){ 76 //overwrite with own async "init signal" 77 if(callback){ 78 initDef.always(callback); 79 } 80 return initDef; 81 }, 82 /** @returns {Boolean} if this engine compilation works asynchronously. 83 * The current implementation works asynchronously (returns TRUE) 84 * 85 * @memberOf PegJsAsyncGenerator.prototype 86 */ 87 isAsyncCompilation: function(){ return true; }, 88 /** 89 * @see PegJsAsyncGenerator#_compileParser 90 * @protected 91 */ 92 _compileParser: function(grammarDefinition, options, onAfterCompileParserResult){ 93 94 //start compilation in web-worker: 95 asyncCompiler.postMessage({ 96 cmd: 'parse', 97 id: onAfterCompileParserResult, 98 config: options, 99 text: grammarDefinition 100 }); 101 102 }, 103 /** 104 * @see PegJsAsyncGenerator#_preparePrintError 105 * @protected 106 */ 107 _preparePrintError: function(){},//<- overwrite with NOOP 108 109 /** 110 * @see PegJsAsyncGenerator#_afterCompileParser 111 * @protected 112 */ 113 _afterCompileParser: function(compileParserModuleFunc){ 114 115 //callback-ID: 116 var taskId = '' + _taskId++; 117 118 //register callback for messages from web-worker: 119 asyncCompiler.addCallback(taskId, function(evtData){ 120 121 if(evtData.error){ 122 123 //handle error message: 124 125 if(printError){ 126 printError(evtData.error); 127 } 128 else { 129 console.error(evtData.error); 130 } 131 132 //////////////////// EARLY EXIT ///////////////// 133 //NOTE this is not the final message from the compiler-thread... 134 return; 135 } 136 137 var hasError = evtData.isError; 138 var grammarParser = evtData.def; 139 140 compileParserModuleFunc(grammarParser, hasError); 141 }); 142 143 return taskId; 144 } 145 }; 146 147 //extend/overload sync-compiler with async-compiler: 148 return $.extend({}, pegjsGen, pegjsAsyncGen); 149 150 }); 151