1 module TTSListener; 2 3 import RuleTranslatorBaseListener; 4 import RuleTranslatorParser: RuleTranslatorParser; 5 import RuleWriter: RuleWriter; 6 import antlr.v4.runtime.ParserRuleContext; 7 import antlr.v4.runtime.tree.ErrorNode; 8 import antlr.v4.runtime.tree.TerminalNode; 9 import std.algorithm.iteration; 10 import std.array; 11 import std.container : SList; 12 import std.format; 13 import std.stdio; 14 import std..string; 15 16 /** 17 * This class provides an empty implementation of {@link RuleTranslatorListener}, 18 * which can be extended to create a listener which only needs to handle a subset 19 * of the available methods. 20 */ 21 public class TTSListener : RuleTranslatorBaseListener { 22 23 debug __gshared short counter; 24 25 private auto stack = SList!(string[])(); 26 27 struct RuleSetting 28 { 29 string language; 30 string ruleName; 31 string className; 32 string baseName; 33 } 34 35 private RuleSetting ruleSetting; 36 37 struct LoopElement 38 { 39 string foreachType; 40 string foreachElementType; 41 ushort foreachIndex; // index must not start at 0 42 } 43 44 private auto loopStack = SList!(LoopElement)(); 45 46 private string foreachElementName; 47 48 private string dottedName; 49 50 private ushort indentLevel; 51 52 private bool funcdefFlag; 53 54 private bool trailerMode; 55 56 private bool ruleRequired = true; 57 58 private bool ruleExists; 59 60 public RuleWriter writer; 61 62 public string withPropertyName; 63 64 public string arguments; 65 66 string[] startText = [ 67 "\n", 68 "override string[] rule" ~ 69 "(${arguments})\n", 70 "{\n", 71 " output.clear;\n\n", 72 " with(${withPropertyName})\n", 73 " {\n" 74 ]; 75 76 string[] closingText = [ 77 "\n", 78 "static this()\n", 79 "{\n", 80 " auto inst = new ${class}();\n", 81 " inst.type = \"${rule}\";\n", 82 " inst.language = \"${language}\";\n", 83 " Repository.register(inst);\n", 84 "}\n" 85 ]; 86 87 /** 88 * {@inheritDoc} 89 * 90 * <p>The default implementation does nothing.</p> 91 */ 92 override public void enterFile_input(RuleTranslatorParser.File_inputContext ctx) { 93 writer.put("module "); 94 } 95 96 /** 97 * {@inheritDoc} 98 * 99 * <p>The default implementation does nothing.</p> 100 */ 101 override public void exitFile_input(RuleTranslatorParser.File_inputContext ctx) { 102 debug { 103 writefln("%s exitFile_input:", counter++); 104 writefln("\truleRequired = %s", ruleRequired); 105 writefln("\truleExits = %s", ruleExists); 106 } 107 writer.indentLevel = -- indentLevel; 108 writer.putnl("}"); 109 if(ruleExists) { 110 with(ruleSetting) { 111 closingText.each!((ref n) => n = n.replace("${class}", 112 className ? className : ruleName)); 113 closingText.each!((ref n) => n = n.replace("${rule}", ruleName)); 114 closingText.each!((ref n) => n = n.replace("${language}", language)); 115 } 116 writer.putnl("return output.data;"); 117 writer.indentLevel = -- indentLevel; 118 writer.putnl("}"); 119 writer.put(closingText); 120 writer.indentLevel = -- indentLevel; 121 writer.putnl("}"); 122 } 123 writer.print; 124 writer.clear; 125 } 126 127 /** 128 * {@inheritDoc} 129 * 130 * <p>The default implementation does nothing.</p> 131 */ 132 override public void exitRule_setting(RuleTranslatorParser.Rule_settingContext ctx) { 133 with(ruleSetting) { 134 if (language) 135 writer.putnl(format("%s.%s;\n", 136 language, 137 className ? className : ruleName 138 ) 139 ); 140 else 141 writer.putnl(format("%s;\n", 142 className ? className : ruleName 143 ) 144 ); 145 } 146 writer.putnl("import std.array;"); 147 writer.putnl("import std.conv;"); 148 writer.putnl("import std.datetime;"); 149 writer.putnl("import rule.Repository;"); 150 writer.putnl("import rule.GeneratedRule;\n"); 151 writer.putnl("auto iterate(R)(R range)"); 152 writer.putnl("{"); 153 writer.putnl(" import std.algorithm : map;"); 154 writer.putnl(" import std.range : enumerate;"); 155 writer.putnl(" import std.typecons : tuple;\n"); 156 157 writer.putnl(" return enumerate(range)"); 158 writer.putnl(" .map!(a => tuple!(\"value\", \"first\", \"last\")(a.value, a.index == 0, a.index + 1 == range.length));"); 159 writer.putnl("}"); 160 } 161 162 /** 163 * {@inheritDoc} 164 * 165 * <p>The default implementation does nothing.</p> 166 */ 167 override public void enterClass_name(RuleTranslatorParser.Class_nameContext ctx) { 168 ruleSetting.className = ctx.getText; 169 } 170 171 /** 172 * {@inheritDoc} 173 * 174 * <p>The default implementation does nothing.</p> 175 */ 176 override public void enterRule_name(RuleTranslatorParser.Rule_nameContext ctx) { 177 ruleSetting.ruleName = ctx.getText; 178 } 179 180 /** 181 * {@inheritDoc} 182 * 183 * <p>The default implementation does nothing.</p> 184 */ 185 override public void enterLanguage(RuleTranslatorParser.LanguageContext ctx) { 186 ruleSetting.language = ""; 187 } 188 /** 189 * {@inheritDoc} 190 * 191 * <p>The default implementation does nothing.</p> 192 */ 193 override public void exitLanguage(RuleTranslatorParser.LanguageContext ctx) { 194 ruleSetting.language = ctx.getText; 195 } 196 197 /** 198 * {@inheritDoc} 199 * 200 * <p>The default implementation does nothing.</p> 201 */ 202 override public void enterImport_stmt(RuleTranslatorParser.Import_stmtContext ctx) { 203 string app; 204 foreach(el; ctx.children[2..$]) 205 app ~= el.getText; 206 writer.putnl(format("import %s;", app)); 207 } 208 209 /** 210 * {@inheritDoc} 211 * 212 * <p>The default implementation does nothing.</p> 213 */ 214 override public void enterBase_rules(RuleTranslatorParser.Base_rulesContext ctx) { 215 ruleSetting.baseName = ctx.getText; 216 } 217 218 /** 219 * {@inheritDoc} 220 * 221 * <p>The default implementation does nothing.</p> 222 */ 223 override public void enterImport_stmts(RuleTranslatorParser.Import_stmtsContext ctx) { } 224 225 /** 226 * {@inheritDoc} 227 * 228 * <p>The default implementation does nothing.</p> 229 */ 230 override public void exitImport_stmts(RuleTranslatorParser.Import_stmtsContext ctx) { 231 if(ruleSetting.className) 232 writer.putnl(format("\nclass %s : %s\n{", ruleSetting.className, ruleSetting.baseName)); 233 else 234 writer.putnl(format("\nclass %s : GeneratedRule\n{", ruleSetting.ruleName)); 235 writer.indentLevel = ++ indentLevel; 236 } 237 238 239 /** 240 * {@inheritDoc} 241 * 242 * <p>The default implementation does nothing.</p> 243 */ 244 override public void exitFunctionName(RuleTranslatorParser.FunctionNameContext ctx) { 245 writer.put(ctx.getText); 246 } 247 /** 248 * {@inheritDoc} 249 * 250 * <p>The default implementation does nothing.</p> 251 */ 252 override public void enterStmt(RuleTranslatorParser.StmtContext ctx) { 253 debug { 254 writefln("%s enterStmt:", counter++); 255 writefln("\truleRequired = %s", ruleRequired); 256 writefln("\truleExits = %s", ruleExists); 257 } 258 if (ruleRequired) { 259 startText.each!((ref n) => n = n.replace("${withPropertyName}", withPropertyName)); 260 startText.each!((ref n) => n = n.replace("${arguments}", arguments)); 261 writer.put(startText); 262 writer.indentLevel = ++ indentLevel; 263 writer.indentLevel = ++ indentLevel; 264 ruleExists = true; 265 ruleRequired = false; 266 } 267 } 268 /** 269 * {@inheritDoc} 270 * 271 * <p>The default implementation does nothing.</p> 272 */ 273 override public void enterFuncdef(RuleTranslatorParser.FuncdefContext ctx) { 274 writer.putnl(""); 275 writer.put("void "); 276 funcdefFlag = true; 277 ruleRequired = false; 278 } 279 280 /** 281 * {@inheritDoc} 282 * 283 * <p>The default implementation does nothing.</p> 284 */ 285 override public void exitFuncdef(RuleTranslatorParser.FuncdefContext ctx) { 286 writer.indentLevel = -- indentLevel; 287 writer.putnl("}"); 288 ruleRequired = true; 289 } 290 291 /** 292 * {@inheritDoc} 293 * 294 * <p>The default implementation does nothing.</p> 295 */ 296 override public void enterParameters(RuleTranslatorParser.ParametersContext ctx) { 297 if (funcdefFlag) 298 { 299 auto spl = splitter(ctx.getText[1..($-1)], ','); 300 writer.putnl('(' ~ spl.map!(a => "T_" ~ a).join(", ") ~ ')'); 301 writer.putnl(" (" ~ spl.map!(a => "T_" ~ a ~ ' ' ~ a).join(", ") ~ ')'); 302 writer.putnl("{"); 303 writer.indentLevel = ++ indentLevel; 304 funcdefFlag = false; 305 } 306 } 307 308 /** 309 * {@inheritDoc} 310 * 311 * <p>The default implementation does nothing.</p> 312 */ 313 override public void enterString_stmt(RuleTranslatorParser.String_stmtContext ctx) { 314 if (!stack.empty) { 315 stack.front ~= format("append(%s)", ctx.children[0].getText); 316 debug { 317 writefln("%s enterString_stmt:", counter++); 318 foreach(el; stack.opSlice) 319 writefln("\t%s", el); 320 } 321 } 322 } 323 324 /** 325 * {@inheritDoc} 326 * 327 * <p>The default implementation does nothing.</p> 328 */ 329 override public void exitVar_stmt(RuleTranslatorParser.Var_stmtContext ctx) { 330 if (!stack.empty) { 331 stack.front ~= format("append(%s)", dottedName); 332 } 333 debug { 334 writefln("%s exitVar_stmt:", counter++); 335 writefln("\tdottedName = %s", dottedName); 336 } 337 } 338 339 /** 340 * When the name of the variable is equal to the foreach element, 341 * we need to append '.value' property 342 */ 343 override public void enterFirst_part_of_dotted_name(RuleTranslatorParser.First_part_of_dotted_nameContext ctx) { 344 dottedName = ctx.getText; 345 if (!loopStack.empty) { 346 import std.algorithm : map; 347 import std.algorithm: canFind; 348 if (array(map!(a => a.foreachElementType)(loopStack[])).canFind(ctx.getText)) { 349 dottedName ~= ".value"; 350 } 351 } 352 debug { 353 writefln("%s enterFirst_part_of_dotted_name:", counter++); 354 writefln("\ttext = %s", ctx.getText); 355 writefln("\tdottedName = %s", dottedName); 356 foreach(el; stack.opSlice) 357 writefln("\t%s", el); 358 } 359 } 360 /** 361 * {@inheritDoc} 362 * 363 * <p>The default implementation does nothing.</p> 364 */ 365 override public void enterDotted_name_part(RuleTranslatorParser.Dotted_name_partContext ctx) { 366 dottedName ~= "." ~ ctx.getText; 367 debug { 368 writefln("%s enterDotted_name_part:", counter++); 369 writefln("\ttext = %s", ctx.getText); 370 writefln("\tdottedName = %s", dottedName); 371 foreach(el; stack.opSlice) 372 writefln("\t%s", el); 373 } 374 } 375 376 /** 377 * {@inheritDoc} 378 * 379 * <p>The default implementation does nothing.</p> 380 */ 381 override public void enterIf_stmt(RuleTranslatorParser.If_stmtContext ctx) { 382 writer.put("if ("); 383 debug { 384 writefln("%s enterIf_stmt:", counter++); 385 foreach(el; stack.opSlice) 386 writefln("\t%s", el); 387 } 388 } 389 /** 390 * {@inheritDoc} 391 * 392 * <p>The default implementation does nothing.</p> 393 */ 394 override public void exitIf_stmt(RuleTranslatorParser.If_stmtContext ctx) { 395 writer.indentLevel = -- indentLevel; 396 writer.putnl("}"); 397 debug { 398 writefln("%s exitIf_stmt:", counter++); 399 foreach(el; stack.opSlice) 400 writefln("\t%s", el); 401 } 402 } 403 404 405 /** 406 * {@inheritDoc} 407 * 408 * <p>The default implementation does nothing.</p> 409 */ 410 override public void exitAtom_dotted_name(RuleTranslatorParser.Atom_dotted_nameContext ctx) { 411 if (!stack.empty) { 412 stack.front ~= dottedName; 413 debug { 414 writefln("%s exitAtom_dotted_name:", counter++); 415 foreach(el; stack.opSlice) 416 writefln("\t%s", el); 417 } 418 } 419 } 420 421 /** 422 * {@inheritDoc} 423 * 424 * <p>The default implementation does nothing.</p> 425 */ 426 override public void enterFunct_name(RuleTranslatorParser.Funct_nameContext ctx) { 427 if (!stack.empty) { 428 stack.front ~= ctx.getText; 429 debug { 430 writefln("%s enterFunct_name: %s", counter++, ctx.getText); 431 foreach(el; stack.opSlice) 432 writefln("\t%s", el); 433 } 434 } 435 } 436 /** 437 * {@inheritDoc} 438 * 439 * <p>The default implementation does nothing.</p> 440 */ 441 override public void enterCondition(RuleTranslatorParser.ConditionContext ctx) { 442 string[] conditionBuf; 443 stack.insert(conditionBuf); 444 debug { 445 writefln("%s enterCondition:", counter++); 446 foreach(el; stack.opSlice) 447 writefln("\t%s", el); 448 } 449 } 450 451 /** 452 * {@inheritDoc} 453 * 454 * <p>The default implementation does nothing.</p> 455 */ 456 override public void exitCondition(RuleTranslatorParser.ConditionContext ctx) { 457 writer.put(stack.front.join); 458 writer.putnl(")"); 459 stack.removeFront; 460 writer.putnl("{"); 461 writer.indentLevel = ++ indentLevel; 462 debug { 463 writefln("%s exitCondition:", counter++); 464 foreach(el; stack.opSlice) 465 writefln("\t%s", el); 466 } 467 } 468 469 /** 470 * {@inheritDoc} 471 * 472 * <p>The default implementation does nothing.</p> 473 */ 474 override public void enterNot(RuleTranslatorParser.NotContext ctx) { 475 stack.front ~= "!"; 476 debug { 477 writefln("%s enterNot:", counter++); 478 foreach(el; stack.opSlice) 479 writefln("\t%s", el); 480 } 481 } 482 483 /** 484 * {@inheritDoc} 485 * 486 * <p>The default implementation does nothing.</p> 487 */ 488 override public void enterFunct_parameters(RuleTranslatorParser.Funct_parametersContext ctx) { 489 if (!stack.empty) { 490 string[] s; 491 stack.insert(s); 492 debug { 493 writefln("%s enterFunct_parameters: %s", counter++, ctx.getText); 494 foreach(el; stack.opSlice) 495 writefln("\t%s", el); 496 } 497 } 498 } 499 /** 500 * {@inheritDoc} 501 * 502 * <p>The default implementation does nothing.</p> 503 */ 504 override public void exitFunct_parameters(RuleTranslatorParser.Funct_parametersContext ctx) { 505 if (!stack.empty) { 506 auto x = stack.front.join(", "); 507 stack.removeFront; 508 stack.front ~= "(" ~ x ~ ")"; 509 debug { 510 writefln("%s exitFunct_parameters:", counter++); 511 foreach(el; stack.opSlice) 512 writefln("\t%s", el); 513 } 514 } 515 } 516 517 /** 518 * {@inheritDoc} 519 * 520 * <p>The default implementation does nothing.</p> 521 */ 522 override public void enterTfpdef_number(RuleTranslatorParser.Tfpdef_numberContext ctx) { 523 if (!stack.empty) { 524 stack.front ~= ctx.getText; 525 debug { 526 writefln("%s enterTfpdef_number(%s):", counter++, trailerMode); 527 foreach(el; stack.opSlice) 528 writefln("\t%s", el); 529 } 530 } 531 } 532 533 /** 534 * {@inheritDoc} 535 * 536 * <p>The default implementation does nothing.</p> 537 */ 538 override public void exitTfpdef_name(RuleTranslatorParser.Tfpdef_nameContext ctx) { 539 if (!stack.empty) { 540 stack.front ~= dottedName; 541 debug { 542 writefln("%s exitTfpdefName:", counter++); 543 foreach(el; stack.opSlice) 544 writefln("\t%s", el); 545 } 546 } 547 } 548 549 /** 550 * {@inheritDoc} 551 * 552 * <p>The default implementation does nothing.</p> 553 */ 554 override public void enterTfpdef_string(RuleTranslatorParser.Tfpdef_stringContext ctx) { 555 if (!stack.empty) { 556 stack.front ~= ctx.getText; 557 debug { 558 writefln("%s enterTfpdef_string:", counter++); 559 foreach(el; stack.opSlice) 560 writefln("\t%s", el); 561 } 562 } 563 } 564 565 /** 566 * {@inheritDoc} 567 * 568 * <p>The default implementation does nothing.</p> 569 */ 570 override public void enterTfpdef_funct_stm(RuleTranslatorParser.Tfpdef_funct_stmContext ctx) { 571 if (!stack.empty) { 572 string[] s; 573 stack.insert(s); 574 debug { 575 writefln("%s enterTfpdef_funct_stm:", counter++); 576 foreach(el; stack.opSlice) 577 writefln("\t%s", el); 578 } 579 } 580 } 581 582 /** 583 * {@inheritDoc} 584 * 585 * <p>The default implementation does nothing.</p> 586 */ 587 override public void exitTfpdef_funct_stm(RuleTranslatorParser.Tfpdef_funct_stmContext ctx) { 588 if (!stack.empty) { 589 auto x = stack.front.join; 590 stack.removeFront; 591 stack.front ~= x; 592 debug { 593 writefln("%s exitTfpdef_funct_stm:", counter++); 594 foreach(el; stack.opSlice) 595 writefln("\t%s", el); 596 } 597 } 598 } 599 600 /** 601 * {@inheritDoc} 602 * 603 * <p>The default implementation does nothing.</p> 604 */ 605 override public void enterElse_e(RuleTranslatorParser.Else_eContext ctx) { 606 writer.indentLevel = -- indentLevel; 607 writer.putnl("}"); 608 writer.putnl("else"); 609 writer.putnl("{"); 610 writer.indentLevel = ++ indentLevel; 611 debug { 612 writefln("%s enterElse_e:", counter++); 613 foreach(el; stack.opSlice) 614 writefln("\t%s", el); 615 } 616 } 617 618 /** 619 * {@inheritDoc} 620 * 621 * <p>The default implementation does nothing.</p> 622 */ 623 override public void enterElif_e(RuleTranslatorParser.Elif_eContext ctx) { 624 writer.indentLevel = -- indentLevel; 625 writer.putnl("}"); 626 writer.put("else if ("); 627 debug { 628 writefln("%s enterElif_e:", counter++); 629 foreach(el; stack.opSlice) 630 writefln("\t%s", el); 631 } 632 } 633 634 /** 635 * {@inheritDoc} 636 * 637 * <p>The default implementation does nothing.</p> 638 */ 639 override public void enterOr_e(RuleTranslatorParser.Or_eContext ctx) { 640 if (!stack.empty) { 641 stack.front ~= " || "; 642 } 643 } 644 645 /** 646 * {@inheritDoc} 647 * 648 * <p>The default implementation does nothing.</p> 649 */ 650 override public void enterAnd_e(RuleTranslatorParser.And_eContext ctx) { 651 if (!stack.empty) { 652 stack.front ~= " && "; 653 debug { 654 writefln("%s enterAnd_e:", counter++); 655 foreach(el; stack.opSlice) 656 writefln("\t%s", el); 657 } 658 } 659 } 660 661 /** 662 * {@inheritDoc} 663 * 664 * <p>The default implementation does nothing.</p> 665 */ 666 override public void enterLess_than(RuleTranslatorParser.Less_thanContext ctx) { 667 if (!stack.empty) { 668 stack.front ~= " < "; 669 debug { 670 writefln("%s enterLess_than:", counter++); 671 foreach(el; stack.opSlice) 672 writefln("\t%s", el); 673 } 674 } 675 } 676 677 /** 678 * {@inheritDoc} 679 * 680 * <p>The default implementation does nothing.</p> 681 */ 682 override public void enterGreater_than(RuleTranslatorParser.Greater_thanContext ctx) { 683 if (!stack.empty) { 684 stack.front ~= " > "; 685 debug { 686 writefln("%s enterGreater_than:", counter++); 687 foreach(el; stack.opSlice) 688 writefln("\t%s", el); 689 } 690 } 691 } 692 693 /** 694 * {@inheritDoc} 695 * 696 * <p>The default implementation does nothing.</p> 697 */ 698 override public void enterGreater_equal(RuleTranslatorParser.Greater_equalContext ctx) { 699 if (!stack.empty) { 700 stack.front ~= " >= "; 701 debug { 702 writefln("%s enterGreater_equal:", counter++); 703 foreach(el; stack.opSlice) 704 writefln("\t%s", el); 705 } 706 } 707 } 708 709 /** 710 * {@inheritDoc} 711 * 712 * <p>The default implementation does nothing.</p> 713 */ 714 override public void enterLess_equal(RuleTranslatorParser.Less_equalContext ctx) { 715 if (!stack.empty) { 716 stack.front ~= " <= "; 717 debug { 718 writefln("%s enterLess_equal:", counter++); 719 foreach(el; stack.opSlice) 720 writefln("\t%s", el); 721 } 722 } 723 } 724 725 /** 726 * {@inheritDoc} 727 * 728 * <p>The default implementation does nothing.</p> 729 */ 730 override public void enterEquals(RuleTranslatorParser.EqualsContext ctx) { 731 if (!stack.empty) { 732 stack.front ~= " == "; 733 debug { 734 writefln("%s enterEquals:", counter++); 735 foreach(el; stack.opSlice) 736 writefln("\t%s", el); 737 } 738 } 739 } 740 741 /** 742 * {@inheritDoc} 743 * 744 * <p>The default implementation does nothing.</p> 745 */ 746 override public void enterNot_equal(RuleTranslatorParser.Not_equalContext ctx) { 747 if (!stack.empty) { 748 stack.front ~= " != "; 749 debug { 750 writefln("%s enterNot_equal:", counter++); 751 foreach(el; stack.opSlice) 752 writefln("\t%s", el); 753 } 754 } 755 } 756 757 /** 758 * {@inheritDoc} 759 * 760 * <p>The default implementation does nothing.</p> 761 */ 762 override public void enterDot_e(RuleTranslatorParser.Dot_eContext ctx) { 763 if (!stack.empty) { 764 stack.front ~= "."; 765 debug { 766 writefln("%s enterDot_e:", counter++); 767 foreach(el; stack.opSlice) 768 writefln("\t%s", el); 769 } 770 } 771 } 772 773 /** 774 * {@inheritDoc} 775 * 776 * <p>The default implementation does nothing.</p> 777 */ 778 override public void enterSmall_stmt(RuleTranslatorParser.Small_stmtContext ctx) { 779 string[] conditionBuf; 780 stack.insert(conditionBuf); 781 debug { 782 writefln("%s enterSmall_stmt:", counter++); 783 foreach(el; stack.opSlice) 784 writefln("\t%s", el); 785 } 786 } 787 788 /** 789 * {@inheritDoc} 790 * 791 * <p>The default implementation does nothing.</p> 792 */ 793 override public void exitSmall_stmt(RuleTranslatorParser.Small_stmtContext ctx) { 794 if (!stack.empty) { 795 writer.put(stack.front.join); 796 writer.putnl(";"); 797 stack.removeFront; 798 debug { 799 writefln("%s exitSmall_stmt:", counter++); 800 foreach(el; stack.opSlice) 801 writefln("\t%s", el); 802 } 803 } 804 } 805 806 /** 807 * {@inheritDoc} 808 * 809 * <p>The default implementation does nothing.</p> 810 */ 811 override public void enterBlock_stmt(RuleTranslatorParser.Block_stmtContext ctx) { 812 string[] conditionBuf; 813 stack.insert(conditionBuf); 814 debug { 815 writefln("%s enterBlock_stmt:", counter++); 816 foreach(el; stack.opSlice) 817 writefln("\t%s", el); 818 } 819 } 820 /** 821 * {@inheritDoc} 822 * 823 * <p>The default implementation does nothing.</p> 824 */ 825 override public void exitBlock_stmt(RuleTranslatorParser.Block_stmtContext ctx) { 826 if (!stack.empty) { 827 writer.putnl(stack.front.join); 828 stack.removeFront; 829 debug { 830 writefln("%s exitBlock_stmt:", counter++); 831 foreach(el; stack.opSlice) 832 writefln("\t%s", el); 833 } 834 }} 835 /** 836 * {@inheritDoc} 837 * 838 * <p>The default implementation does nothing.</p> 839 */ 840 override public void enterNumber_e(RuleTranslatorParser.Number_eContext ctx) { 841 if (!stack.empty && !trailerMode) { 842 stack.front ~= ctx.getText; 843 debug { 844 writefln("%s enterNumber_e(%s):", counter++, trailerMode); 845 foreach(el; stack.opSlice) 846 writefln("\t%s", el); 847 } 848 } 849 } 850 851 /** 852 * {@inheritDoc} 853 * 854 * <p>The default implementation does nothing.</p> 855 */ 856 override public void enterString_e(RuleTranslatorParser.String_eContext ctx) { 857 if (!stack.empty) 858 stack.front ~= ctx.getText; 859 debug { 860 writefln("%s enterString_e:", counter++); 861 foreach(el; stack.opSlice) 862 writefln("\t%s", el); 863 } 864 } 865 866 /** 867 * {@inheritDoc} 868 * 869 * <p>The default implementation does nothing.</p> 870 */ 871 override public void enterAtom_funct_stmt(RuleTranslatorParser.Atom_funct_stmtContext ctx) { 872 if (!stack.empty) { 873 string[] s; 874 stack.insert(s); 875 debug { 876 writefln("%s enterAtom_funct_stmt:", counter++); 877 foreach(el; stack.opSlice) 878 writefln("\t%s", el); 879 } 880 } 881 } 882 883 /** 884 * {@inheritDoc} 885 * 886 * <p>The default implementation does nothing.</p> 887 */ 888 override public void exitAtom_funct_stmt(RuleTranslatorParser.Atom_funct_stmtContext ctx) { 889 if (!stack.empty) { 890 auto x = stack.front; 891 stack.removeFront; 892 stack.front ~= x; 893 debug { 894 writefln("%s exitAtom_funct_stmt:", counter++); 895 foreach(el; stack.opSlice) 896 writefln("\t%s", el); 897 } 898 } 899 } 900 901 /** 902 * {@inheritDoc} 903 * 904 * <p>The default implementation does nothing.</p> 905 */ 906 override public void enterTrue_e(RuleTranslatorParser.True_eContext ctx) { 907 if (!stack.empty) 908 stack.front ~= "true"; 909 debug { 910 writefln("%s enterTrue_e:", counter++); 911 foreach(el; stack.opSlice) 912 writefln("\t%s", el); 913 } 914 } 915 916 /** 917 * {@inheritDoc} 918 * 919 * <p>The default implementation does nothing.</p> 920 */ 921 override public void enterFalse_e(RuleTranslatorParser.False_eContext ctx) { 922 if (!stack.empty) 923 stack.front ~= "false"; 924 debug { 925 writefln("%s enterFalse_e:", counter++); 926 foreach(el; stack.opSlice) 927 writefln("\t%s", el); 928 } 929 } 930 931 /** 932 * {@inheritDoc} 933 * 934 * <p>The default implementation does nothing.</p> 935 */ 936 override public void enterFor_stmt(RuleTranslatorParser.For_stmtContext ctx) { 937 LoopElement l; 938 loopStack.insert(l); 939 writer.put("foreach ("); 940 } 941 942 /** 943 * {@inheritDoc} 944 * 945 * <p>The default implementation does nothing.</p> 946 */ 947 override public void exitFor_stmt(RuleTranslatorParser.For_stmtContext ctx) { 948 writer.indentLevel = -- indentLevel; 949 writer.putnl("}"); 950 debug { 951 writefln("%s exitFor_stm:", counter++); 952 foreach(el; loopStack.opSlice) 953 writefln("\t%s", el); 954 } 955 loopStack.removeFront; 956 } 957 958 /** 959 * {@inheritDoc} 960 * 961 * <p>The default implementation does nothing.</p> 962 */ 963 override public void enterFor_exprlist(RuleTranslatorParser.For_exprlistContext ctx) { 964 foreachElementName = ctx.getText; 965 } 966 967 /** 968 * {@inheritDoc} 969 * 970 * <p>The default implementation does nothing.</p> 971 */ 972 override public void enterFor_testlist(RuleTranslatorParser.For_testlistContext ctx) { 973 LoopElement l; 974 l.foreachElementType = foreachElementName; 975 l.foreachType = ctx.getText; 976 l.foreachIndex = 0; 977 loopStack.front = l; 978 debug { 979 writefln("%s enterFor_testlist loop stack:", counter++); 980 foreach(el; loopStack.opSlice) 981 writefln("\t%s", el); 982 } 983 } 984 985 /** 986 * {@inheritDoc} 987 * 988 * <p>The default implementation does nothing.</p> 989 */ 990 override public void exitFor_testlist(RuleTranslatorParser.For_testlistContext ctx) 991 { 992 writer.putnl(format("%s; %s.iterate)", 993 loopStack.front.foreachElementType, 994 loopStack.front.foreachType, 995 ) 996 ); 997 writer.putnl("{"); 998 writer.indentLevel = ++ indentLevel; 999 debug { 1000 writefln("%s exitFor_testlist:", counter++); 1001 foreach(el; loopStack.opSlice) 1002 writefln("\t%s", el); 1003 } 1004 } 1005 1006 /** 1007 * {@inheritDoc} 1008 * 1009 * <p>The default implementation does nothing.</p> 1010 */ 1011 override public void enterFirst_e(RuleTranslatorParser.First_eContext ctx) { 1012 if (!stack.empty) 1013 stack.front ~= format("%s.first", 1014 loopStack.front.foreachElementType, 1015 ); 1016 } 1017 1018 /** 1019 * {@inheritDoc} 1020 * 1021 * <p>The default implementation does nothing.</p> 1022 */ 1023 override public void enterLast_e(RuleTranslatorParser.Last_eContext ctx) { 1024 if (!stack.empty) 1025 stack.front ~= format("%s.last", 1026 loopStack.front.foreachElementType); 1027 } 1028 /** 1029 * {@inheritDoc} 1030 * 1031 * <p>The default implementation does nothing.</p> 1032 */ 1033 override public void enterAdd(RuleTranslatorParser.AddContext ctx) { 1034 if (!stack.empty) { 1035 stack.front ~= " + "; 1036 debug { 1037 writefln("%s enterAdd:", counter++); 1038 foreach(el; stack.opSlice) 1039 writefln("\t%s", el); 1040 } 1041 } 1042 } 1043 1044 /** 1045 * {@inheritDoc} 1046 * 1047 * <p>The default implementation does nothing.</p> 1048 */ 1049 override public void enterMinus(RuleTranslatorParser.MinusContext ctx) { 1050 if (!stack.empty) { 1051 stack.front ~= " - "; 1052 debug { 1053 writefln("%s enterMinus:", counter++); 1054 foreach(el; stack.opSlice) 1055 writefln("\t%s", el); 1056 } 1057 } 1058 } 1059 1060 /** 1061 * {@inheritDoc} 1062 * 1063 * <p>The default implementation does nothing.</p> 1064 */ 1065 override public void enterTrailer(RuleTranslatorParser.TrailerContext ctx) { 1066 trailerMode = true; 1067 } 1068 /** 1069 * {@inheritDoc} 1070 * 1071 * <p>The default implementation does nothing.</p> 1072 */ 1073 override public void exitTrailer(RuleTranslatorParser.TrailerContext ctx) { 1074 trailerMode = false; 1075 } 1076 }