1 /* 2 * Copyright (C) 2012-2013 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 define([ 'core', 'commonUtils', 'parserModule', 'parsingResult' 29 , 'ES3Lexer', 'ES3Parser', 'contentLexer', 'contentParser' 30 , 'scriptLexer', 'scriptParser', 'antlr3' 31 ], 32 /** 33 * Main implementation for parsing (view) templates. 34 * 35 * @class 36 * @name TemplateProcessor 37 * @memberOf mmir.parser 38 * @static 39 * @public 40 * 41 * @depends ParserUtils#printInfo ("hidden" dependency when printing log-messages; accessed through the passed-in theLexerInstance) 42 */ 43 function ( 44 mmir, commonUtils, parser, ParsingResult 45 , ES3Lexer, ES3Parser, MmirScriptContentLexer, MmirScriptContentParser 46 , MmirScriptLexer, MmirScriptParser, org 47 ){//hidden dependency: templateParserUtils (for parser.printInfo) 48 49 //TODO move to separate file (extension-file): 50 //START extensions 51 /** 52 * @memberOf ES3Parser.prototype 53 */ 54 ES3Parser.prototype.getVarReferences = function(){ 55 56 var size = this.ampersatIdentifiers.length; 57 58 if(size === 0){ 59 return null; 60 } 61 62 var varRefs = new Array(size); 63 for(var i=0; i < size; ++i){ 64 var ref = this.ampersatIdentifiers[i]; 65 66 var refObj = new ParsingResult(ref); 67 // refObj.start = ref.start; 68 69 //correct end-position (token's stop-index is exactly the last char-index, whereas ParsingResult's end-position is token.stopIndex + 1) 70 refObj.end = refObj.getEnd() + 1; 71 72 refObj.type = parser.element.VAR_REFERENCE; 73 74 varRefs[i] = refObj; 75 } 76 return varRefs; 77 }; 78 //END extensions 79 80 81 /** 82 * @type TemplateParser 83 * @memberOf mmir.parser.TemplateProcessor# 84 */ 85 var parserModule = parser; 86 87 /** 88 * "Processor" for the template parse-results: 89 * 90 * This function is used by the generated (antlr) parsers. 91 * 92 * @memberOf mmir.parser.TemplateProcessor# 93 * @constructor 94 * @ignore 95 */ 96 function _extend(theLexerInstance) { 97 98 /** @scope mmir.parser.TemplateProcessor.prototype */ 99 100 101 /** 102 * @type Number 103 * @private 104 * @memberOf mmir.parser.TemplateProcessor# 105 */ 106 var INTERNAL_INCLUDE_SCRIPT = parser.element.INCLUDE_SCRIPT; 107 theLexerInstance.INTERNAL_INCLUDE_SCRIPT = INTERNAL_INCLUDE_SCRIPT; 108 /** 109 * @type Number 110 * @private 111 * @memberOf mmir.parser.TemplateProcessor# 112 */ 113 var INTERNAL_INCLUDE_STYLE = parser.element.INCLUDE_STYLE; 114 theLexerInstance.INTERNAL_INCLUDE_STYLE = INTERNAL_INCLUDE_STYLE; 115 /** 116 * @type Number 117 * @private 118 * @memberOf mmir.parser.TemplateProcessor# 119 */ 120 var INTERNAL_LOCALIZE = parser.element.LOCALIZE; 121 theLexerInstance.INTERNAL_LOCALIZE = INTERNAL_LOCALIZE; 122 /** 123 * @type Number 124 * @private 125 * @memberOf mmir.parser.TemplateProcessor# 126 */ 127 var INTERNAL_YIELD_DECLARATION = parser.element.YIELD_DECLARATION; 128 theLexerInstance.INTERNAL_YIELD_DECLARATION = INTERNAL_YIELD_DECLARATION; 129 /** 130 * @type Number 131 * @private 132 * @memberOf mmir.parser.TemplateProcessor# 133 */ 134 var INTERNAL_YIELD_CONTENT = parser.element.YIELD_CONTENT; 135 theLexerInstance.INTERNAL_YIELD_CONTENT = INTERNAL_YIELD_CONTENT; 136 /** 137 * @type Number 138 * @private 139 * @memberOf mmir.parser.TemplateProcessor# 140 */ 141 var INTERNAL_BLOCK = parser.element.BLOCK; 142 theLexerInstance.INTERNAL_BLOCK = INTERNAL_BLOCK; 143 /** 144 * @type Number 145 * @private 146 * @memberOf mmir.parser.TemplateProcessor# 147 */ 148 var INTERNAL_STATEMENT = parser.element.STATEMENT; 149 theLexerInstance.INTERNAL_STATEMENT = INTERNAL_STATEMENT; 150 /** 151 * @type Number 152 * @private 153 * @memberOf mmir.parser.TemplateProcessor# 154 */ 155 var INTERNAL_HELPER = parser.element.HELPER; 156 theLexerInstance.INTERNAL_HELPER = INTERNAL_HELPER; 157 /** 158 * @type Number 159 * @private 160 * @memberOf mmir.parser.TemplateProcessor# 161 */ 162 var INTERNAL_IF = parser.element.IF; 163 theLexerInstance.INTERNAL_IF = INTERNAL_IF; 164 /** 165 * @type Number 166 * @private 167 * @memberOf mmir.parser.TemplateProcessor# 168 */ 169 var INTERNAL_ELSE = parser.element.ELSE; 170 theLexerInstance.INTERNAL_ELSE = INTERNAL_ELSE; 171 /** 172 * @type Number 173 * @private 174 * @memberOf mmir.parser.TemplateProcessor# 175 */ 176 var INTERNAL_FOR = parser.element.FOR; 177 theLexerInstance.INTERNAL_FOR = INTERNAL_FOR; 178 /** 179 * @type Number 180 * @private 181 * @memberOf mmir.parser.TemplateProcessor# 182 */ 183 var INTERNAL_RENDER = parser.element.RENDER; 184 theLexerInstance.INTERNAL_RENDER = INTERNAL_RENDER; 185 /** 186 * @type Number 187 * @private 188 * @memberOf mmir.parser.TemplateProcessor# 189 */ 190 var INTERNAL_ESCAPE_ENTER = parser.element.ESCAPE_ENTER; 191 theLexerInstance.INTERNAL_ESCAPE_ENTER = INTERNAL_ESCAPE_ENTER; 192 /** 193 * @type Number 194 * @private 195 * @memberOf mmir.parser.TemplateProcessor# 196 */ 197 var INTERNAL_ESCAPE_EXIT = parser.element.ESCAPE_EXIT; 198 theLexerInstance.INTERNAL_ESCAPE_EXIT = INTERNAL_ESCAPE_EXIT; 199 200 /** 201 * @type Number 202 * @private 203 * @memberOf mmir.parser.TemplateProcessor# 204 */ 205 var INTERNAL_FOR_TYPE_ITER = parser.element.FOR_TYPE_ITER; 206 theLexerInstance.INTERNAL_FOR_TYPE_ITER = INTERNAL_FOR_TYPE_ITER; 207 /** 208 * @type Number 209 * @private 210 * @memberOf mmir.parser.TemplateProcessor# 211 */ 212 var INTERNAL_FOR_TYPE_STEP = parser.element.FOR_TYPE_STEP; 213 theLexerInstance.INTERNAL_FOR_TYPE_STEP = INTERNAL_FOR_TYPE_STEP; 214 215 /** 216 * @type Number 217 * @private 218 * @memberOf mmir.parser.TemplateProcessor# 219 */ 220 var INTERNAL_VAR_DECLARATION = parser.element.VAR_DECLARATION; 221 theLexerInstance.INTERNAL_VAR_DECLARATION = INTERNAL_VAR_DECLARATION; 222 /** 223 * @type Number 224 * @private 225 * @memberOf mmir.parser.TemplateProcessor# 226 */ 227 var INTERNAL_VAR_REFERENCE = parser.element.VAR_REFERENCE; 228 theLexerInstance.INTERNAL_VAR_REFERENCE = INTERNAL_VAR_REFERENCE; 229 230 /** 231 * @type Number 232 * @private 233 * @memberOf mmir.parser.TemplateProcessor# 234 */ 235 var INTERNAL_COMMENT = parser.element.COMMENT; 236 theLexerInstance.INTERNAL_COMMENT = INTERNAL_COMMENT; 237 238 /** 239 * @type Number 240 * @private 241 * @memberOf mmir.parser.TemplateProcessor# 242 */ 243 //"shortcut" for accessing the IF-type 244 var IF_TYPE = theLexerInstance.INTERNAL_IF; 245 246 //internal "static" definitions for parsing mode/type 247 248 /** 249 * @private 250 * @memberOf mmir.parser.TemplateProcessor# 251 */ 252 var PARSER_SCRIPT_BLOCK = 0; 253 theLexerInstance.PARSER_SCRIPT_BLOCK = PARSER_SCRIPT_BLOCK; 254 /** 255 * @private 256 * @memberOf mmir.parser.TemplateProcessor# 257 */ 258 var PARSER_SCRIPT_STATMENT = 2; 259 theLexerInstance.PARSER_SCRIPT_STATMENT = PARSER_SCRIPT_STATMENT; 260 /** 261 * @private 262 * @memberOf mmir.parser.TemplateProcessor# 263 */ 264 var PARSER_SCRIPT_CONTENT = 4; 265 theLexerInstance.PARSER_SCRIPT_CONTENT = PARSER_SCRIPT_CONTENT; 266 /** 267 * @private 268 * @memberOf mmir.parser.TemplateProcessor# 269 */ 270 var PARSER_JS_CODE = 8; 271 theLexerInstance.PARSER_JS_CODE = PARSER_JS_CODE; 272 273 274 /** 275 * @private 276 * @memberOf mmir.parser.TemplateProcessor# 277 */ 278 var isDebug = true; 279 theLexerInstance.isDebug = isDebug; 280 281 282 /** 283 * @private 284 * @memberOf mmir.parser.TemplateProcessor# 285 */ 286 var SCRIPT_CHANNEL = 1; 287 theLexerInstance.SCRIPT_CHANNEL = SCRIPT_CHANNEL; 288 //theLexerInstance.nesting = 0; 289 290 291 /** 292 * @private 293 * @memberOf mmir.parser.TemplateProcessor# 294 */ 295 theLexerInstance.scriptBlocks = new Array(); 296 /** 297 * @private 298 * @memberOf mmir.parser.TemplateProcessor# 299 */ 300 theLexerInstance.scriptStatements = new Array(); 301 /** 302 * @private 303 * @memberOf mmir.parser.TemplateProcessor# 304 */ 305 theLexerInstance.includeScripts = new Array(); 306 /** 307 * @private 308 * @memberOf mmir.parser.TemplateProcessor# 309 */ 310 theLexerInstance.includeStyles = new Array(); 311 /** 312 * @private 313 * @memberOf mmir.parser.TemplateProcessor# 314 */ 315 theLexerInstance.locales = new Array(); 316 /** 317 * @private 318 * @memberOf mmir.parser.TemplateProcessor# 319 */ 320 theLexerInstance.helpers = new Array(); 321 /** 322 * @private 323 * @memberOf mmir.parser.TemplateProcessor# 324 */ 325 theLexerInstance.renderPartials = new Array(); 326 327 /** 328 * @private 329 * @memberOf mmir.parser.TemplateProcessor# 330 */ 331 theLexerInstance.escape = new Array(); 332 333 /** 334 * @private 335 * @memberOf mmir.parser.TemplateProcessor# 336 */ 337 theLexerInstance.ifs = new Array(); 338 /** 339 * @private 340 * @memberOf mmir.parser.TemplateProcessor# 341 */ 342 theLexerInstance.fors = new Array(); 343 344 /** 345 * @private 346 * @memberOf mmir.parser.TemplateProcessor# 347 */ 348 theLexerInstance.yields = new Array(); 349 /** 350 * @private 351 * @memberOf mmir.parser.TemplateProcessor# 352 */ 353 theLexerInstance.yieldContents = new Array(); 354 355 /** 356 * @private 357 * @memberOf mmir.parser.TemplateProcessor# 358 */ 359 theLexerInstance.vars = new Array(); 360 /** 361 * @private 362 * @memberOf mmir.parser.TemplateProcessor# 363 */ 364 theLexerInstance.comments = new Array(); 365 366 /** 367 * @private 368 * @memberOf mmir.parser.TemplateProcessor# 369 */ 370 theLexerInstance.lastParsedElement = null; 371 372 /** 373 * @function 374 * @private 375 * @memberOf mmir.parser.TemplateProcessor# 376 */ 377 var isArray = commonUtils.isArray; 378 379 /** 380 * @param tokenType 381 * @param parser 382 * 383 * @private 384 * @memberOf mmir.parser.TemplateProcessor# 385 */ 386 var getTokenName = (function(){ 387 388 var _jsTokens = null; 389 390 return function getTokenNameImpl(tokenType, parser){ 391 392 if(!_jsTokens){ 393 _jsTokens = parser.getTokenNames(); 394 } 395 return _jsTokens[tokenType]; 396 }; 397 398 })(); 399 //theLexerInstance.getTokenName = getTokenName; 400 401 /** 402 * @private 403 * @memberOf mmir.parser.TemplateProcessor# 404 */ 405 function getFirstChild(treeNode, strChildType, parser){ 406 var type = getTokenName(treeNode.getType(), parser); 407 if(type === strChildType){ 408 return treeNode; 409 } 410 else { 411 if(treeNode.getChildCount() === 0){ 412 return null; 413 } 414 else { 415 for(var i = 0, size = treeNode.getChildCount(); i < size; ++i){ 416 var result = getFirstChild(treeNode.getChild(i), strChildType, parser); 417 if(result !== null){ 418 return result; 419 } 420 } 421 return null; 422 } 423 } 424 } 425 426 /** 427 * @private 428 * @memberOf mmir.parser.TemplateProcessor# 429 */ 430 function extractBoundries(subTree, buffer){ 431 432 var start = subTree.getToken().getStartIndex(); 433 if(typeof start === 'number' && start !== -1){ 434 if(!buffer){ 435 buffer ={ 436 start: null, 437 stop: null 438 }; 439 } 440 441 if(buffer.start == null || start < buffer.start){ 442 buffer.start = start; 443 } 444 var end = subTree.getToken().getStopIndex(); 445 if(buffer.end == null || end > buffer.end){ 446 buffer.end = end; 447 } 448 } 449 450 if(subTree.getChildCount() === 0){ 451 return buffer; 452 } 453 else { 454 for(var i = 0, size = subTree.getChildCount(); i < size; ++i){ 455 buffer = extractBoundries(subTree.getChild(i), buffer); 456 } 457 return buffer; 458 } 459 } 460 461 /** 462 * @private 463 * @memberOf mmir.parser.TemplateProcessor# 464 */ 465 function getBoundries(treeNode){ 466 467 return { 468 start : treeNode.getToken().getStartIndex(), 469 end : treeNode.stopIndex +1 470 }; 471 } 472 473 /** 474 * @private 475 * @memberOf mmir.parser.TemplateProcessor# 476 */ 477 function getStringFor(boundriesObj, tokens, offset){ 478 479 if(!boundriesObj){ 480 return ''; 481 } 482 483 var start = boundriesObj.start - offset; 484 var end = boundriesObj.end - offset; 485 return tokens.toString().substring(start,end+1); 486 487 } 488 /** 489 * @private 490 * @memberOf mmir.parser.TemplateProcessor# 491 */ 492 function getStringForSubTree(treeNode, tokens, offset){ 493 494 var start = treeNode.getToken().getStartIndex() - offset; 495 var end = treeNode.stopIndex - offset; 496 return tokens.toString().substring(start,end+1); 497 498 } 499 500 /** 501 * @private 502 * @memberOf mmir.parser.TemplateProcessor# 503 */ 504 function createJSObjectFrom(parseElement, parentObject, parser){ 505 506 var type = getTokenName(parseElement.getType(), parser); 507 if('StringLiteral' === type){ 508 var str = parseElement.getText(); 509 return str.substring(1,str.length - 1); 510 } 511 else if ( 'NAMEDVALUE' === type ){ 512 513 var name = createJSObjectFrom(parseElement.getChild(0), null, parser); 514 515 var value = createJSObjectFrom(parseElement.getChild(1), null, parser); 516 517 if(!parentObject){ 518 parentObject = new Object(); 519 } 520 521 parentObject[name] = value; 522 523 return parentObject; 524 } 525 else if ( 'OBJECT' === type ){ 526 527 var theValue = new Object(); 528 var current = null; 529 530 for(var data_index = 0, data_size = parseElement.getChildCount(); data_index < data_size; ++ data_index){ 531 current = parseElement.getChild(data_index); 532 theValue = createJSObjectFrom(current, theValue, parser); 533 } 534 return theValue; 535 } 536 else if ( 'ARRAY' === type ){ 537 538 var array_size = parseElement.getChildCount(); 539 var theValue = new Array(); 540 var current = null; 541 542 for(var array_index = 0; array_index < array_size; ++ array_index){ 543 current = parseElement.getChild(array_index); 544 theValue[array_index] = createJSObjectFrom(current.getChild(0), theValue, parser); 545 } 546 return theValue; 547 } 548 else { 549 return parseElement.getText(); 550 } 551 } 552 //theLexerInstance.createJSObjectFrom = createJSObjectFrom; 553 554 /** 555 * @private 556 * @memberOf mmir.parser.TemplateProcessor# 557 */ 558 function processBlock(parsingObj, result, tokens){ 559 560 parsingObj.scriptContent = result; 561 562 if(!parsingObj.scriptContent){ 563 if(theLexerInstance.isDebug) parser.parserPrintWarning('[TemplateProcessor - BLOCK] WARNING: ','invalid "script block" at ['+parsingObj.start+','+parsingObj.end+'] -> "'+theLexerInstance.input.data.substring(parsingObj.start,parsingObj.end)+'"');//debug 564 return; 565 } 566 567 theLexerInstance.scriptBlocks.push(parsingObj); 568 569 } 570 theLexerInstance.processBlock = processBlock; 571 572 /** 573 * @private 574 * @memberOf mmir.parser.TemplateProcessor# 575 */ 576 function processStatement(parsingObj, result, tokens){ 577 578 parsingObj.scriptContent = result; 579 580 if(!parsingObj.scriptContent){ 581 if(theLexerInstance.isDebug) parser.parserPrintWarning('[TemplateProcessor - STATEMENT] WARNING: ','invalid "script statement" at ['+parsingObj.start+','+parsingObj.end+'] -> "'+theLexerInstance.input.data.substring(parsingObj.start,parsingObj.end)+'"');//debug 582 return; 583 } 584 585 theLexerInstance.scriptStatements.push(parsingObj); 586 587 } 588 theLexerInstance.processStatement = processStatement; 589 590 /** 591 * @private 592 * @memberOf mmir.parser.TemplateProcessor# 593 */ 594 function processIncludeScript (parsingObj, result, tokens, parser){ 595 596 var tree = result.tree; 597 var offset = tokens.tokens[0].getStartIndex(); 598 599 parsingObj.scriptPathType = getTokenName( tree.getChild(0).getType(), parser); 600 parsingObj.scriptPath = getStringForSubTree(tree.getChild(0), tokens, offset);//createJSObjectFrom(tree.getChild(0), null, parser ); 601 602 if(!parsingObj.scriptPath){ 603 if(theLexerInstance.isDebug) parser.parserPrintWarning('[TemplateProcessor - SCRIPT LINK] WARNING: ','invalid "include script statement" at ['+parsingObj.start+','+parsingObj.end+'] -> "'+theLexerInstance.input.data.substring(parsingObj.start,parsingObj.end)+'"');//debug 604 return; 605 } 606 607 theLexerInstance.includeScripts.push(parsingObj); 608 609 } 610 theLexerInstance.processIncludeScript = processIncludeScript; 611 612 /** 613 * @private 614 * @memberOf mmir.parser.TemplateProcessor# 615 */ 616 function processIncludeStyle(parsingObj, result, tokens, parser){ 617 618 var tree = result.tree; 619 var offset = tokens.tokens[0].getStartIndex(); 620 621 parsingObj.stylePathType = getTokenName( tree.getChild(0).getType(), parser); 622 parsingObj.stylePath = getStringForSubTree(tree.getChild(0), tokens, offset);//createJSObjectFrom(tree.getChild(0), null, parser ); 623 624 if(!parsingObj.stylePath){ 625 if(theLexerInstance.isDebug) parser.parserPrintWarning('[TemplateProcessor - STYLE LINK] WARNING: ','invalid "include style statement" at ['+parsingObj.start+','+parsingObj.end+'] -> "'+theLexerInstance.input.data.substring(parsingObj.start,parsingObj.end)+'"');//debug 626 return; 627 } 628 629 theLexerInstance.includeStyles.push(parsingObj); 630 631 } 632 theLexerInstance.processIncludeStyle = processIncludeStyle; 633 634 /** 635 * @private 636 * @memberOf mmir.parser.TemplateProcessor# 637 */ 638 function processLocalize(parsingObj, result, tokens, parser){ 639 640 var tree = result.tree; 641 var offset = tokens.tokens[0].getStartIndex(); 642 643 parsingObj.nameType = getTokenName( tree.getChild(0).getType(), parser); 644 parsingObj.name = getStringForSubTree(tree.getChild(0), tokens, offset);//createJSObjectFrom(tree.getChild(0), null, parser ); 645 646 if(!parsingObj.name || parsingObj.name.length === 0){ 647 if(theLexerInstance.isDebug) parser.parserPrintWarning('[TemplateProcessor - LOCALIZE] WARNING: ','invalid "localize statement" at ['+parsingObj.start+','+parsingObj.end+'] -> "'+theLexerInstance.input.data.substring(parsingObj.start,parsingObj.end)+'"');//debug 648 return; 649 } 650 651 theLexerInstance.locales.push(parsingObj); 652 653 } 654 theLexerInstance.processLocalize = processLocalize; 655 656 /** 657 * @private 658 * @memberOf mmir.parser.TemplateProcessor# 659 */ 660 function processDeclareVar(parsingObj, result, tokens, parser){ 661 662 var tree = result.tree; 663 var offset = tokens.tokens[0].getStartIndex(); 664 665 parsingObj.nameType = getTokenName( tree.getChild(0).getType(), parser); 666 parsingObj.name = getStringForSubTree(tree.getChild(0), tokens, offset);//createJSObjectFrom(tree.getChild(0), null, parser ); 667 668 if(!parsingObj.name || parsingObj.name.length === 0){ 669 if(theLexerInstance.isDebug) parser.parserPrintWarning('[TemplateProcessor - VAR DECLARATION] WARNING: ','invalid "var declaration statement" at ['+parsingObj.start+','+parsingObj.end+'] -> "'+theLexerInstance.input.data.substring(parsingObj.start,parsingObj.end)+'"');//debug 670 return; 671 } 672 673 theLexerInstance.vars.push(parsingObj); 674 675 } 676 theLexerInstance.processDeclareVar = processDeclareVar; 677 678 /** 679 * @private 680 * @memberOf mmir.parser.TemplateProcessor# 681 */ 682 function processHelperFunction(parsingObj, result, tokens, parser){ 683 684 var tree = result.tree; 685 var offset = tokens.tokens[0].getStartIndex(); 686 687 parsingObj.helperType = getTokenName( tree.getChild(0).getType(), parser); 688 // parsingObj.helper = createJSObjectFrom(tree.getChild(0), null, parser ); 689 parsingObj.helper = getStringForSubTree(tree.getChild(0), tokens, offset); 690 691 if(tree.getChildCount() === 2){ 692 parsingObj.dataType = getTokenName( tree.getChild(1).getType(), parser); 693 // var param = null; 694 // if('OBJECT' === parsingObj.dataType){ 695 // param = new Object(); 696 // } 697 // parsingObj.dataArg = createJSObjectFrom(tree.getChild(1), param, parser ); 698 699 parsingObj.dataPos = getBoundries(tree.getChild(1)); 700 701 } 702 703 if(!parsingObj.helper || parsingObj.helper.length === 0){ 704 if(theLexerInstance.isDebug) parser.parserPrintWarning('[TemplateProcessor - HELPER CALL] WARNING: ','invalid "helper function statement" at ['+parsingObj.start+','+parsingObj.end+'] -> "'+theLexerInstance.input.data.substring(parsingObj.start,parsingObj.end)+'"');//debug 705 return; 706 } 707 708 theLexerInstance.helpers.push(parsingObj); 709 710 } 711 theLexerInstance.processHelperFunction = processHelperFunction; 712 713 /** 714 * @private 715 * @memberOf mmir.parser.TemplateProcessor# 716 */ 717 function processRenderPartial(parsingObj, result, tokens, parser){ 718 719 //parsingObj.controllerName = result.controller; 720 //parsingObj.partialName = result.partial; 721 //parsingObj.arguments = result.arguments; 722 723 724 var tree = result.tree; 725 var offset = tokens.tokens[0].getStartIndex(); 726 727 parsingObj.controllerType = getTokenName( tree.getChild(0).getType(), parser); 728 // parsingObj.controller = createJSObjectFrom(tree.getChild(0), null, parser ); 729 parsingObj.controller = getStringForSubTree(tree.getChild(0), tokens, offset); 730 731 parsingObj.partialType = getTokenName( tree.getChild(1).getType(), parser); 732 // parsingObj.partial = createJSObjectFrom(tree.getChild(1), null, parser ); 733 parsingObj.partial = getStringForSubTree(tree.getChild(1), tokens, offset); 734 735 if(tree.getChildCount() === 3){ 736 parsingObj.dataType = getTokenName( tree.getChild(2).getType(), parser); 737 // var param = null; 738 // if('OBJECT' === parsingObj.dataType){ 739 // param = new Object(); 740 // } 741 // parsingObj.dataArg = createJSObjectFrom(tree.getChild(2), param, parser ); 742 743 // parsingObj.dataArg = getStringForSubTree(tree.getChild(2), tokens, offset); 744 parsingObj.dataPos = getBoundries(tree.getChild(2)); 745 746 } 747 748 if(false){//!parsingObj.partialName || parsingObj.partialName.length === 0){ TODO implement check 749 if(theLexerInstance.isDebug) parser.parserPrintWarning('[TemplateProcessor - RENDER PARTIAL] WARNING: ','invalid "render partial statement" at ['+parsingObj.start+','+parsingObj.end+'] -> "'+theLexerInstance.input.data.substring(parsingObj.start,parsingObj.end)+'"');//debug 750 return; 751 } 752 753 theLexerInstance.renderPartials.push(parsingObj); 754 755 } 756 theLexerInstance.processRenderPartial = processRenderPartial; 757 758 /** 759 * @private 760 * @memberOf mmir.parser.TemplateProcessor# 761 */ 762 function processYieldDeclaration(parsingObj, result, tokens, parser){ 763 764 var tree = result.tree; 765 var offset = tokens.tokens[0].getStartIndex(); 766 767 parsingObj.nameType = getTokenName( tree.getChild(0).getType(), parser); 768 parsingObj.name = getStringForSubTree(tree.getChild(0), tokens, offset);//createJSObjectFrom(tree.getChild(0), null, parser ); 769 770 if(!parsingObj.name || parsingObj.name.length === 0){ 771 if(theLexerInstance.isDebug) parser.parserPrintWarning('[TemplateProcessor - YIELD DECLARATION] WARNING: ','invalid "yield declaration" at ['+parsingObj.start+','+parsingObj.end+'] -> "'+theLexerInstance.input.data.substring(parsingObj.start,parsingObj.end)+'"');//debug 772 return; 773 } 774 775 theLexerInstance.yields.push(parsingObj); 776 777 } 778 theLexerInstance.processYieldDeclaration = processYieldDeclaration; 779 780 /** 781 * @private 782 * @memberOf mmir.parser.TemplateProcessor# 783 */ 784 function processYieldContentParam (parsingObj, result, tokens, parser){ 785 786 var tree = result.tree; 787 var offset = tokens.tokens[0].getStartIndex(); 788 789 parsingObj.nameType = getTokenName( tree.getChild(0).getType(), parser); 790 parsingObj.name = getStringForSubTree(tree.getChild(0), tokens, offset);//createJSObjectFrom(tree.getChild(0), null, parser ); 791 parsingObj.contentOffset = parsingObj.end + 1 + 2;// +2: "){" 792 793 if(!parsingObj.name){ 794 if(theLexerInstance.isDebug) parser.parserPrintWarning('[TemplateProcessor - YIELD CONTENT PARAMETER] WARNING: ','invalid "content for specification" (missing name) at ['+parsingObj.start+','+parsingObj.end+'] -> "'+theLexerInstance.input.data.substring(parsingObj.start,parsingObj.end)+'"');//debug 795 return; 796 } 797 } 798 theLexerInstance.processYieldContentParam = processYieldContentParam; 799 800 /** 801 * @private 802 * @memberOf mmir.parser.TemplateProcessor# 803 */ 804 function processYieldContent (parsingObj, result, tokens){ 805 806 parsingObj.content = result; 807 808 if(!parsingObj.content){ 809 if(theLexerInstance.isDebug) parser.parserPrintWarning('[TemplateProcessor - YIELD CONTENT] WARNING: ','invalid "content for specification" (missing content) at ['+parsingObj.start+','+parsingObj.end+'] -> "'+theLexerInstance.input.data.substring(parsingObj.start,parsingObj.end)+'"');//debug 810 return; 811 } 812 813 theLexerInstance.yieldContents.push(parsingObj); 814 815 } 816 theLexerInstance.processYieldContent = processYieldContent; 817 818 /** 819 * @private 820 * @memberOf mmir.parser.TemplateProcessor# 821 */ 822 function processIfExpr (parsingObj, result, tokens, parser){ 823 824 //TODO validate expr! (e.g. detect assignments to undeclared variables...) 825 // var tree = result.tree; 826 // parsingObj.exprType = getTokenName( tree.getChild(0).getType(), parser); 827 // parsingObj.expr = createJSObjectFrom(tree.getChild(0), null, parser ); 828 parsingObj.contentOffset = parsingObj.end + 1 + 2;// +2: "){" 829 830 // var lastElem = theLexerInstance.lastParsedElement; 831 parsingObj.ifExpr = tokens.toString(); 832 833 if(!parsingObj.ifExpr){ 834 if(theLexerInstance.isDebug) parser.parserPrintWarning('[TemplateProcessor - IF EXPR] WARNING: ','invalid "if statement" (missing expression) at ['+parsingObj.start+','+parsingObj.end+'] -> "'+theLexerInstance.input.data.substring(parsingObj.start,parsingObj.end)+'"');//debug 835 return; 836 } 837 } 838 theLexerInstance.processIfExpr = processIfExpr; 839 840 /** 841 * @private 842 * @memberOf mmir.parser.TemplateProcessor# 843 */ 844 function processIfContent (parsingObj, result, tokens){ 845 846 parsingObj.content = result; 847 848 if(!parsingObj.content){ 849 if(theLexerInstance.isDebug) parser.parserPrintWarning('[TemplateProcessor - IF CONTENT] WARNING: ','invalid "if statement" (missing content) at ['+parsingObj.start+','+parsingObj.end+'] -> "'+theLexerInstance.input.data.substring(parsingObj.start,parsingObj.end)+'"');//debug 850 return; 851 } 852 853 theLexerInstance.ifs.push(parsingObj); 854 855 } 856 theLexerInstance.processIfContent = processIfContent; 857 858 /** 859 * @private 860 * @memberOf mmir.parser.TemplateProcessor# 861 */ 862 function processElse (parsingObj, result, tokens){ 863 864 parsingObj.content = result; 865 866 if(!parsingObj.content){ 867 if(theLexerInstance.isDebug) parser.parserPrintWarning('[TemplateProcessor - ELSE CONTENT] WARNING: ','invalid "else statement" (missing content) at ['+parsingObj.start+','+parsingObj.end+'] -> "'+theLexerInstance.input.data.substring(parsingObj.start,parsingObj.end)+'"');//debug 868 return; 869 } 870 871 parsingObj.contentOffset = parsingObj.start + 1;// +1: "{" 872 873 var lastElem = theLexerInstance.lastParsedElement; 874 if(lastElem.type !== IF_TYPE){ 875 if(theLexerInstance.isDebug) parser.parserPrintWarning('[TemplateProcessor - ELSE CONTENT] WARNING: ','invalid "else statement" (missing content) at ['+parsingObj.start+','+parsingObj.end+'] -> "'+theLexerInstance.input.data.substring(parsingObj.start,parsingObj.end)+'"');//debug 876 877 throw new org.antlr.runtime.NoViableAltException('invalid else statement: missing preceeding IF!', -1, -1, tokens); 878 } 879 880 var lastIf = theLexerInstance.ifs[theLexerInstance.ifs.length-1]; 881 if(lastIf.elseContent){ 882 883 if(theLexerInstance.isDebug) parser.parserPrintWarning('[TemplateProcessor - ELSE CONTENT] WARNING: ','invalid "else statement" (ELSE already defined) at ['+parsingObj.start+','+parsingObj.end+'] -> "'+theLexerInstance.input.data.substring(parsingObj.start,parsingObj.end)+'"');//debug 884 885 throw new org.antlr.runtime.NoViableAltException('invalid else statement: too many ELSE definitions - ELSE clause is already defined!', -1, -1, tokens); 886 } 887 888 lastIf.elseContent = parsingObj; 889 //redefine getEnd of the if-element: use end of else-statement 890 lastIf.getEnd = function(){ 891 return this.elseContent.getEnd(); 892 }; 893 } 894 theLexerInstance.processElse = processElse; 895 896 /** 897 * @private 898 * @memberOf mmir.parser.TemplateProcessor# 899 */ 900 function processForControl (parsingObj, result, tokens, parser){ 901 902 //TODO validate expr! (e.g. detect assignments to undeclared variables...) 903 var tree = result.tree; 904 var offset = tokens.tokens[0].getStartIndex(); 905 906 parsingObj.forControlType = getTokenName( tree.getChild(0).getType(), parser); 907 //parsingObj.forControl = createJSObjectFrom(tree.getChild(0), null, parser ); 908 909 parsingObj.contentOffset = parsingObj.end + 1 + 2;// +2: "){" 910 911 // parsingObj.forControl = tokens.toString(); 912 913 if(parsingObj.forControlType === 'FORITER'){ 914 // parsingObj.forIterationExpr = getFirstChild(tree.getChild(0).getChild(0), 'Identifier', parser).toString(); 915 // parsingObj.forObjectExpr = getFirstChild(tree.getChild(0).getChild(1), 'Identifier', parser).toString(); 916 parsingObj.forControlVarPos = parser.getVarReferences(); 917 parsingObj.forControlPos = extractBoundries(tree.getChild(0)); 918 } 919 else { 920 //-> type is 'FORSTEP' 921 parsingObj.forInitExpr = getStringFor( extractBoundries(tree.getChild(0).getChild(0)), tokens, offset); 922 parsingObj.forConditionExpr = getStringFor( extractBoundries(tree.getChild(0).getChild(1)), tokens, offset); 923 parsingObj.forIncrementExpr = getStringFor( extractBoundries(tree.getChild(0).getChild(2)), tokens, offset); 924 } 925 926 // if(!parsingObj.expr){ 927 // if(theLexerInstance.isDebug) parser.parserPrintWarning('[TemplateProcessor - FOR EXPR] WARNING: ','invalid "for statement" (missing control statement) at ['+parsingObj.start+','+parsingObj.end+'] -> "'+theLexerInstance.input.data.substring(parsingObj.start,parsingObj.end)+'"');//debug 928 // return; 929 // } 930 } 931 theLexerInstance.processForControl = processForControl; 932 933 /** 934 * @private 935 * @memberOf mmir.parser.TemplateProcessor# 936 */ 937 function processForContent (parsingObj, result, tokens){ 938 939 parsingObj.content = result; 940 941 if(!parsingObj.content){ 942 if(theLexerInstance.isDebug) parser.parserPrintWarning('[TemplateProcessor - FOR CONTENT] WARNING: ','invalid "for statement" (missing content) at ['+parsingObj.start+','+parsingObj.end+'] -> "'+theLexerInstance.input.data.substring(parsingObj.start,parsingObj.end)+'"');//debug 943 return; 944 } 945 946 theLexerInstance.fors.push(parsingObj); 947 948 } 949 theLexerInstance.processForContent = processForContent; 950 951 /** 952 * @private 953 * @memberOf mmir.parser.TemplateProcessor# 954 */ 955 function getLexerFor(self, parserType, input){ 956 if(self.PARSER_SCRIPT_BLOCK === parserType){ 957 var scriptLexer = new MmirScriptLexer(input); 958 scriptLexer.setBlockMode(); 959 return scriptLexer; 960 } 961 else if(self.PARSER_SCRIPT_STATEMENT === parserType){ 962 var scriptLexer = new MmirScriptLexer(input); 963 scriptLexer.setStatementMode(); 964 return scriptLexer; 965 } 966 else if(self.PARSER_SCRIPT_CONTENT === parserType){ 967 return new MmirScriptContentLexer(input); 968 } 969 else if(self.PARSER_JS_CODE === parserType){ 970 return new ES3Lexer(input); 971 } 972 parser.parserPrintWarning('[TemplateProcessor - creating Lexer] WARNING: ','getLexerFor unkonwn parser type '+parserType); 973 return null; 974 }; 975 976 /** 977 * @private 978 * @memberOf mmir.parser.TemplateProcessor# 979 */ 980 function getParserFor(self, parserType, tokens){ 981 if(self.PARSER_SCRIPT_BLOCK === parserType){ 982 return new MmirScriptParser(tokens); 983 } 984 else if(self.PARSER_SCRIPT_STATEMENT === parserType){ 985 return new MmirScriptParser(tokens); 986 } 987 else if(self.PARSER_SCRIPT_CONTENT === parserType){ 988 return new MmirScriptContentParser(tokens); 989 } 990 else if(self.PARSER_JS_CODE === parserType){ 991 return new ES3Parser(tokens); 992 } 993 parser.parserPrintWarning('[TemplateProcessor - creating parser] WARNING: ','getParserFor unkonwn parser type '+parserType); 994 return null; 995 }; 996 997 /** 998 * @private 999 * @memberOf mmir.parser.TemplateProcessor# 1000 */ 1001 function doEnter(parserType, self, currentChannel, entryFunc, processFunc, parseResultObject, msg){ 1002 1003 if(!entryFunc){ 1004 entryFunc = 'main'; 1005 } 1006 1007 if(!parseResultObject){ 1008 parseResultObject = null; 1009 if(typeof processFunc !== 'function'){ 1010 msg = processFunc; 1011 processFunc = null; 1012 } 1013 } 1014 if(!msg){ 1015 msg = ''; 1016 } 1017 1018 if(self.isDebug) theLexerInstance.printDebug('enter embedded '+msg);//debug 1019 1020 var lexer = getLexerFor(self, parserType, self.input); 1021 1022 lexer.isDebug = self.isDebug; 1023 var tokens = new org.antlr.runtime.CommonTokenStream(lexer); 1024 1025 1026 var result; 1027 if(parseResultObject){ 1028 result = parseResultObject; 1029 result.setEndFrom(tokens); 1030 } 1031 else { 1032 result = new ParsingResult(tokens); 1033 } 1034 1035 if(self.isDebug){//debug 1036 //alert(msg+'\n'+JSON.stringify(result)); 1037 var start = result.start;//tokens.getTokens()[0].getStartIndex(); 1038 var end = result.end;//tokens.getTokens()[tokens.size()-1].getStopIndex(); 1039 1040 theLexerInstance.printInfo(msg+'_tokens('+start+'->'+end+')',tokens); 1041 } 1042 1043 var parser = getParserFor(self, parserType, tokens); 1044 1045 parser.isDebug = self.isDebug; 1046 var parseResult = parser[entryFunc](); 1047 1048 if(self.isDebug) theLexerInstance.printDebug(msg+'.'+entryFunc+'() result: >'+parseResult+'<');//debug 1049 1050 if(result.rawResult){ 1051 if(isArray(result.rawResult)){ 1052 result.rawResult.push(rawResults); 1053 } 1054 else { 1055 var rawResults = new Array(2); 1056 rawResults[0] = result.rawResult; 1057 rawResults[1] = parseResult; 1058 result.rawResult = rawResults; 1059 } 1060 } 1061 else { 1062 result.rawResult = parseResult; 1063 } 1064 1065 if(parserType === self.PARSER_JS_CODE){ 1066 var varRefs = parser.getVarReferences(); 1067 if(varRefs){ 1068 if(result.varReferences){ 1069 result.varReferences = result.varReferences.concat(varRefs); 1070 } 1071 else{ 1072 result.varReferences = varRefs; 1073 } 1074 } 1075 } 1076 1077 if(typeof processFunc === 'function'){ 1078 processFunc(result, parseResult, tokens, parser); 1079 } 1080 1081 //FIXME NOOP? currentChannel is a function argument... 1082 1083 // returns a SCRIPT token to the java parser but on a 1084 // different channel than the normal token stream so it 1085 // doesn't get in the way. 1086 currentChannel = theLexerInstance.SCRIPT_CHANNEL; 1087 1088 theLexerInstance.lastParsedElement = result; 1089 1090 return result; 1091 }; 1092 1093 /** 1094 * @private 1095 * @memberOf mmir.parser.TemplateProcessor# 1096 */ 1097 function processEscape(replacementText, msg){ 1098 1099 if(msg && typeof self !== 'undefined' && self.isDebug){//debug 1100 theLexerInstance.printInfo(msg); 1101 } 1102 1103 var result = new ParsingResult(null); 1104 result.text = replacementText; 1105 this.escape.push(result); 1106 1107 return result; 1108 }; 1109 theLexerInstance.processEscape = processEscape; 1110 1111 /** 1112 * @private 1113 * @memberOf mmir.parser.TemplateProcessor# 1114 */ 1115 function processComment(msg){ 1116 1117 if(msg && typeof self !== 'undefined' && self.isDebug){//debug 1118 theLexerInstance.printInfo(msg); 1119 } 1120 1121 var result = new ParsingResult(null); 1122 this.comments.push(result); 1123 1124 return result; 1125 }; 1126 theLexerInstance.processComment = processComment; 1127 1128 /** 1129 * @private 1130 * @memberOf mmir.parser.TemplateProcessor# 1131 */ 1132 function enterBlock(currentChannel, entryFunc, processFunc, msg, parseResultObject){ 1133 return doEnter(theLexerInstance.PARSER_SCRIPT_BLOCK, theLexerInstance, currentChannel, entryFunc, processFunc, parseResultObject, msg); 1134 }; 1135 theLexerInstance.enterBlock = enterBlock; 1136 1137 /** 1138 * @private 1139 * @memberOf mmir.parser.TemplateProcessor# 1140 */ 1141 function enterScript(currentChannel, entryFunc, processFunc, msg, parseResultObject){ 1142 return doEnter(theLexerInstance.PARSER_SCRIPT_STATEMENT, theLexerInstance, currentChannel, entryFunc, processFunc, parseResultObject, msg); 1143 }; 1144 theLexerInstance.enterScript = enterScript; 1145 1146 /** 1147 * @private 1148 * @memberOf mmir.parser.TemplateProcessor# 1149 */ 1150 function enterContent(currentChannel, entryFunc, processFunc, msg, parseResultObject){ 1151 return doEnter(theLexerInstance.PARSER_SCRIPT_CONTENT, theLexerInstance, currentChannel, entryFunc, processFunc, parseResultObject, msg); 1152 }; 1153 theLexerInstance.enterContent = enterContent; 1154 1155 /** 1156 * @private 1157 * @memberOf mmir.parser.TemplateProcessor# 1158 */ 1159 function enterJavaScript(currentChannel, entryFunc, processFunc, msg, parseResultObject){ 1160 return doEnter(theLexerInstance.PARSER_JS_CODE, theLexerInstance, currentChannel, entryFunc, processFunc, parseResultObject, msg); 1161 }; 1162 theLexerInstance.enterJavaScript = enterJavaScript; 1163 1164 };//END: extendMmirTemplateProcessor(){ 1165 1166 parser.extendMmirTemplateProcessor = _extend; 1167 1168 1169 return _extend; 1170 1171 });//END: define 1172 1173 1174