1 using System; 2 using System.Collections; 3 using Assembly = System.Reflection.Assembly; 4 using ArrayList = System.Collections.ArrayList; 5 using Debug = System.Diagnostics.Debug; 6 using AST = antlr.collections.AST; 7 using ASTArray = antlr.collections.impl.ASTArray; 8 using ANTLRException = antlr.ANTLRException; 9 10 namespace antlr 11 { 12 /*ANTLR Translator Generator 13 * Project led by Terence Parr at http://www.jGuru.com 14 * Software rights: http://www.antlr.org/license.html 15 * 16 * $Id:$ 17 */ 18 19 // 20 // ANTLR C# Code Generator by Micheal Jordan 21 // Kunle Odutola : kunle UNDERSCORE odutola AT hotmail DOT com 22 // Anthony Oguntimehin 23 // 24 // With many thanks to Eric V. Smith from the ANTLR list. 25 // 26 27 28 // HISTORY: 29 // 30 // 19-Aug-2002 kunle Augmented the basic flexibility of the default ASTFactory with a map 31 // of TokenID-to-NodeTypeName. It's now a proper GoF-style Factory ;-) 32 // 33 34 /// <summary> 35 /// AST Support code shared by TreeParser and Parser. 36 /// </summary> 37 /// <remarks> 38 /// <para> 39 /// We use delegation to share code (and have only one 40 /// bit of code to maintain) rather than subclassing 41 /// or superclassing (forces AST support code to be 42 /// loaded even when you don't want to do AST stuff). 43 /// </para> 44 /// <para> 45 /// Typically, <see cref="setASTNodeType"/> is used to specify the 46 /// homogeneous type of node to create, but you can override 47 /// <see cref="create"/> to make heterogeneous nodes etc... 48 /// </para> 49 /// </remarks> 50 public class ASTFactory 51 { 52 //--------------------------------------------------------------------- 53 // CONSTRUCTORS 54 //--------------------------------------------------------------------- 55 56 /// <summary> 57 /// Constructs an <c>ASTFactory</c> with the default AST node type of 58 /// <see cref="antlr.CommonAST"/>. 59 /// </summary> ASTFactory()60 public ASTFactory() : this(typeof(antlr.CommonAST)) 61 { 62 } 63 64 /// <summary> 65 /// Constructs an <c>ASTFactory</c> and use the specified AST node type 66 /// as the default. 67 /// </summary> 68 /// <param name="nodeTypeName"> 69 /// Name of default AST node type for this factory. 70 /// </param> ASTFactory(string nodeTypeName)71 public ASTFactory(string nodeTypeName) 72 : this( loadNodeTypeObject(nodeTypeName) ) 73 { 74 } 75 76 /// <summary> 77 /// Constructs an <c>ASTFactory</c> and use the specified AST node type 78 /// as the default. 79 /// </summary> 80 /// <param name="nodeType"> 81 /// MetaType of default AST node type for this factory. 82 /// </param> ASTFactory(Type nodeType)83 public ASTFactory(Type nodeType) 84 { 85 heteroList_ = new FactoryEntry[Token.MIN_USER_TYPE+1]; 86 defaultASTNodeTypeObject_ = nodeType; 87 defaultCreator_ = null; 88 typename2creator_ = new Hashtable(32, (float) 0.3); 89 typename2creator_["antlr.CommonAST"] = CommonAST.Creator; 90 typename2creator_["antlr.CommonASTWithHiddenTokens"] = CommonASTWithHiddenTokens.Creator; 91 92 } 93 94 //--------------------------------------------------------------------- 95 // DATA MEMBERS 96 //--------------------------------------------------------------------- 97 98 /// <summary> 99 /// Stores the Type of the default AST node class to be used during tree construction. 100 /// </summary> 101 protected Type defaultASTNodeTypeObject_; 102 protected ASTNodeCreator defaultCreator_; 103 104 /// <summary> 105 /// Stores the mapping between custom AST NodeTypes and their NodeTypeName/NodeTypeClass 106 /// and ASTNodeCreator. 107 /// </summary> 108 protected FactoryEntry[] heteroList_; 109 110 /// <summary> 111 /// Stores the mapping between AST node typenames and their token ID. 112 /// </summary> 113 protected Hashtable typename2creator_; 114 115 //--------------------------------------------------------------------- 116 // FUNCTION MEMBERS 117 //--------------------------------------------------------------------- 118 119 /// <summary> 120 /// Specify an "override" for the <see cref="AST"/> type created for 121 /// the specified Token type. 122 /// </summary> 123 /// <remarks> 124 /// This method is useful for situations that ANTLR cannot oridinarily deal 125 /// with (i.e., when you create a token based upon a nonliteral token symbol 126 /// like #[LT(1)]. This is a runtime value and ANTLR cannot determine the token 127 /// type (and hence the AST) statically. 128 /// </remarks> 129 /// <param name="tokenType">Token type to override.</param> 130 /// <param name="NodeTypeName"> 131 /// Fully qualified AST typename (or null to specify 132 /// the factory's default AST type). 133 /// </param> setTokenTypeASTNodeType(int tokenType, string NodeTypeName)134 public void setTokenTypeASTNodeType(int tokenType, string NodeTypeName) 135 { 136 // check validity of arguments... 137 if( tokenType < Token.MIN_USER_TYPE ) 138 throw new ANTLRException("Internal parser error: Cannot change AST Node Type for Token ID '" + tokenType + "'"); 139 140 // resize up to and including 'type' and initialize any gaps to default 141 // factory. 142 if (tokenType > (heteroList_.Length+1)) 143 setMaxNodeType(tokenType); 144 // And add new thing.. 145 if (heteroList_[tokenType] == null) 146 heteroList_[tokenType] = new FactoryEntry(loadNodeTypeObject(NodeTypeName)); 147 else 148 heteroList_[tokenType].NodeTypeObject = loadNodeTypeObject(NodeTypeName); 149 } 150 151 /// <summary> 152 /// Register an AST Node Type for a given Token type ID. 153 /// </summary> 154 /// <param name="NodeType">The Token type ID.</param> 155 /// <param name="NodeTypeName">The AST Node Type to register.</param> 156 [Obsolete("Replaced by setTokenTypeASTNodeType(int, string) since version 2.7.2.6", true)] registerFactory(int NodeType, string NodeTypeName)157 public void registerFactory(int NodeType, string NodeTypeName) 158 { 159 setTokenTypeASTNodeType(NodeType, NodeTypeName); 160 } 161 162 /// <summary> 163 /// Register an ASTNodeCreator for a given Token type ID. 164 /// </summary> 165 /// <param name="NodeType">The Token type ID.</param> 166 /// <param name="creator">The creater to register.</param> setTokenTypeASTNodeCreator(int NodeType, ASTNodeCreator creator)167 public void setTokenTypeASTNodeCreator(int NodeType, ASTNodeCreator creator) 168 { 169 // check validity of arguments... 170 if( NodeType < Token.MIN_USER_TYPE ) 171 throw new ANTLRException("Internal parser error: Cannot change AST Node Type for Token ID '" + NodeType + "'"); 172 173 // resize up to and including 'type' and initialize any gaps to default 174 // factory. 175 if (NodeType > (heteroList_.Length+1)) 176 setMaxNodeType(NodeType); 177 // And add new thing.. 178 if (heteroList_[NodeType] == null) 179 heteroList_[NodeType] = new FactoryEntry(creator); 180 else 181 heteroList_[NodeType].Creator = creator; 182 183 //typename2creator_[NodeType.ToString()] = creator; 184 typename2creator_[creator.ASTNodeTypeName] = creator; 185 } 186 187 /// <summary> 188 /// Register an ASTNodeCreator to be used for creating node by default. 189 /// </summary> 190 /// <param name="creator">The ASTNodeCreator.</param> setASTNodeCreator(ASTNodeCreator creator)191 public void setASTNodeCreator(ASTNodeCreator creator) 192 { 193 defaultCreator_ = creator; 194 } 195 196 /// <summary> 197 /// Pre-expands the internal list of TokenTypeID-to-ASTNodeType mappings 198 /// to the specified size. 199 /// This is primarily a convenience method that can be used to prevent 200 /// unnecessary and costly re-org of the mappings list. 201 /// </summary> 202 /// <param name="NodeType">Maximum Token Type ID.</param> setMaxNodeType( int NodeType )203 public void setMaxNodeType( int NodeType ) 204 { 205 //Debug.WriteLine(this, "NodeType = " + NodeType + " and NodeList.Length = " + nodeTypeList_.Length); 206 if (heteroList_ == null) 207 { 208 heteroList_ = new FactoryEntry[NodeType+1]; 209 } 210 else 211 { 212 int length = heteroList_.Length; 213 214 if ( NodeType >= length ) 215 { 216 FactoryEntry[] newList = new FactoryEntry[NodeType+1]; 217 Array.Copy(heteroList_, 0, newList, 0, length); 218 heteroList_ = newList; 219 } 220 else if ( NodeType < length ) 221 { 222 FactoryEntry[] newList = new FactoryEntry[NodeType+1]; 223 Array.Copy(heteroList_, 0, newList, 0, (NodeType+1)); 224 heteroList_ = newList; 225 } 226 } 227 //Debug.WriteLine(this, "NodeType = " + NodeType + " and NodeList.Length = " + nodeTypeList_.Length); 228 } 229 230 /// <summary> 231 /// Add a child to the current AST 232 /// </summary> 233 /// <param name="currentAST">The AST to add a child to</param> 234 /// <param name="child">The child AST to be added</param> addASTChild(ref ASTPair currentAST, AST child)235 public virtual void addASTChild(ref ASTPair currentAST, AST child) 236 { 237 if (child != null) 238 { 239 if (currentAST.root == null) 240 { 241 // Make new child the current root 242 currentAST.root = child; 243 } 244 else 245 { 246 if (currentAST.child == null) 247 { 248 // Add new child to current root 249 currentAST.root.setFirstChild(child); 250 } 251 else 252 { 253 currentAST.child.setNextSibling(child); 254 } 255 } 256 // Make new child the current child 257 currentAST.child = child; 258 currentAST.advanceChildToEnd(); 259 } 260 } 261 262 /// <summary> 263 /// Creates a new uninitialized AST node. Since a specific AST Node Type 264 /// wasn't indicated, the new AST node is created using the current default 265 /// AST Node type - <see cref="defaultASTNodeTypeObject_"/> 266 /// </summary> 267 /// <returns>An uninitialized AST node object.</returns> create()268 public virtual AST create() 269 { 270 AST newNode; 271 272 if (defaultCreator_ == null) 273 newNode = createFromNodeTypeObject(defaultASTNodeTypeObject_); 274 else 275 newNode = defaultCreator_.Create(); 276 277 return newNode; 278 } 279 280 /// <summary> 281 /// Creates and initializes a new AST node using the specified Token Type ID. 282 /// The <see cref="System.Type"/> used for creating this new AST node is 283 /// determined by the following: 284 /// <list type="bullet"> 285 /// <item>the current TokenTypeID-to-ASTNodeType mapping (if any) or,</item> 286 /// <item>the <see cref="defaultASTNodeTypeObject_"/> otherwise</item> 287 /// </list> 288 /// </summary> 289 /// <param name="type">Token type ID to be used to create new AST Node.</param> 290 /// <returns>An initialized AST node object.</returns> create(int type)291 public virtual AST create(int type) 292 { 293 AST newNode = createFromNodeType(type); 294 newNode.initialize(type, ""); 295 return newNode; 296 } 297 298 /// <summary> 299 /// Creates and initializes a new AST node using the specified Token Type ID. 300 /// The <see cref="System.Type"/> used for creating this new AST node is 301 /// determined by the following: 302 /// <list type="bullet"> 303 /// <item>the current TokenTypeID-to-ASTNodeType mapping (if any) or,</item> 304 /// <item>the <see cref="defaultASTNodeTypeObject_"/> otherwise</item> 305 /// </list> 306 /// </summary> 307 /// <param name="type">Token type ID to be used to create new AST Node.</param> 308 /// <param name="txt">Text for initializing the new AST Node.</param> 309 /// <returns>An initialized AST node object.</returns> create(int type, string txt)310 public virtual AST create(int type, string txt) 311 { 312 AST newNode = createFromNodeType(type); 313 newNode.initialize(type, txt); 314 return newNode; 315 } 316 317 /// <summary> 318 /// Creates a new AST node using the specified AST Node Type name. Once created, 319 /// the new AST node is initialized with the specified Token type ID and string. 320 /// The <see cref="System.Type"/> used for creating this new AST node is 321 /// determined solely by <c>ASTNodeTypeName</c>. 322 /// The AST Node type must have a default/parameterless constructor. 323 /// </summary> 324 /// <param name="type">Token type ID to be used to create new AST Node.</param> 325 /// <param name="txt">Text for initializing the new AST Node.</param> 326 /// <param name="ASTNodeTypeName">Fully qualified name of the Type to be used for creating the new AST Node.</param> 327 /// <returns>An initialized AST node object.</returns> create(int type, string txt, string ASTNodeTypeName)328 public virtual AST create(int type, string txt, string ASTNodeTypeName) 329 { 330 AST newNode = createFromNodeName(ASTNodeTypeName); 331 newNode.initialize(type, txt); 332 return newNode; 333 } 334 335 /// <summary> 336 /// Creates a new AST node using the specified AST Node Type name. 337 /// </summary> 338 /// <param name="tok">Token instance to be used to initialize the new AST Node.</param> 339 /// <param name="ASTNodeTypeName"> 340 /// Fully qualified name of the Type to be used for creating the new AST Node. 341 /// </param> 342 /// <returns>A newly created and initialized AST node object.</returns> 343 /// <remarks> 344 /// Once created, the new AST node is initialized with the specified Token 345 /// instance. The <see cref="System.Type"/> used for creating this new AST 346 /// node is determined solely by <c>ASTNodeTypeName</c>. 347 /// <para>The AST Node type must have a default/parameterless constructor.</para> 348 /// </remarks> create(IToken tok, string ASTNodeTypeName)349 public virtual AST create(IToken tok, string ASTNodeTypeName) 350 { 351 AST newNode = createFromNodeName(ASTNodeTypeName); 352 newNode.initialize(tok); 353 return newNode; 354 } 355 356 /// <summary> 357 /// Creates and initializes a new AST node using the specified AST Node instance. 358 /// the new AST node is initialized with the specified Token type ID and string. 359 /// The <see cref="System.Type"/> used for creating this new AST node is 360 /// determined solely by <c>aNode</c>. 361 /// The AST Node type must have a default/parameterless constructor. 362 /// </summary> 363 /// <param name="aNode">AST Node instance to be used for creating the new AST Node.</param> 364 /// <returns>An initialized AST node object.</returns> create(AST aNode)365 public virtual AST create(AST aNode) 366 { 367 AST newNode; 368 369 if (aNode == null) 370 newNode = null; 371 else 372 { 373 newNode = createFromAST(aNode); 374 newNode.initialize(aNode); 375 } 376 return newNode; 377 } 378 379 /// <summary> 380 /// Creates and initializes a new AST node using the specified Token instance. 381 /// The <see cref="System.Type"/> used for creating this new AST node is 382 /// determined by the following: 383 /// <list type="bullet"> 384 /// <item>the current TokenTypeID-to-ASTNodeType mapping (if any) or,</item> 385 /// <item>the <see cref="defaultASTNodeTypeObject_"/> otherwise</item> 386 /// </list> 387 /// </summary> 388 /// <param name="tok">Token instance to be used to create new AST Node.</param> 389 /// <returns>An initialized AST node object.</returns> create(IToken tok)390 public virtual AST create(IToken tok) 391 { 392 AST newNode; 393 394 if (tok == null) 395 newNode = null; 396 else 397 { 398 newNode = createFromNodeType(tok.Type); 399 newNode.initialize(tok); 400 } 401 return newNode; 402 } 403 404 /// <summary> 405 /// Returns a copy of the specified AST Node instance. The copy is obtained by 406 /// using the <see cref="ICloneable"/> method Clone(). 407 /// </summary> 408 /// <param name="t">AST Node to copy.</param> 409 /// <returns>An AST Node (or null if <c>t</c> is null).</returns> dup(AST t)410 public virtual AST dup(AST t) 411 { 412 // The Java version is implemented using code like this: 413 if (t == null) 414 return null; 415 416 AST dup_edNode = createFromAST(t); 417 dup_edNode.initialize(t); 418 return dup_edNode; 419 } 420 421 /// <summary> 422 /// Duplicate AST Node tree rooted at specified AST node and all of it's siblings. 423 /// </summary> 424 /// <param name="t">Root of AST Node tree.</param> 425 /// <returns>Root node of new AST Node tree (or null if <c>t</c> is null).</returns> dupList(AST t)426 public virtual AST dupList(AST t) 427 { 428 AST result = dupTree(t); // if t == null, then result==null 429 AST nt = result; 430 while (t != null) 431 { 432 // for each sibling of the root 433 t = t.getNextSibling(); 434 nt.setNextSibling(dupTree(t)); // dup each subtree, building new tree 435 nt = nt.getNextSibling(); 436 } 437 return result; 438 } 439 440 /// <summary> 441 /// Duplicate AST Node tree rooted at specified AST node. Ignore it's siblings. 442 /// </summary> 443 /// <param name="t">Root of AST Node tree.</param> 444 /// <returns>Root node of new AST Node tree (or null if <c>t</c> is null).</returns> dupTree(AST t)445 public virtual AST dupTree(AST t) 446 { 447 AST result = dup(t); // make copy of root 448 // copy all children of root. 449 if (t != null) 450 { 451 result.setFirstChild(dupList(t.getFirstChild())); 452 } 453 return result; 454 } 455 456 /// <summary> 457 /// Make a tree from a list of nodes. The first element in the 458 /// array is the root. If the root is null, then the tree is 459 /// a simple list not a tree. Handles null children nodes correctly. 460 /// For example, build(a, b, null, c) yields tree (a b c). build(null,a,b) 461 /// yields tree (nil a b). 462 /// </summary> 463 /// <param name="nodes">List of Nodes.</param> 464 /// <returns>AST Node tree.</returns> make(params AST[] nodes)465 public virtual AST make(params AST[] nodes) 466 { 467 if (nodes == null || nodes.Length == 0) 468 return null; 469 AST root = nodes[0]; 470 AST tail = null; 471 if (root != null) 472 { 473 root.setFirstChild(null); // don't leave any old pointers set 474 } 475 // link in children; 476 for (int i = 1; i < nodes.Length; i++) 477 { 478 if (nodes[i] == null) 479 continue; 480 // ignore null nodes 481 if (root == null) 482 { 483 // Set the root and set it up for a flat list 484 root = (tail = nodes[i]); 485 } 486 else if (tail == null) 487 { 488 root.setFirstChild(nodes[i]); 489 tail = root.getFirstChild(); 490 } 491 else 492 { 493 tail.setNextSibling(nodes[i]); 494 tail = tail.getNextSibling(); 495 } 496 // Chase tail to last sibling 497 while (tail.getNextSibling() != null) 498 { 499 tail = tail.getNextSibling(); 500 } 501 } 502 return root; 503 } 504 505 /// <summary> 506 /// Make a tree from a list of nodes, where the nodes are contained 507 /// in an ASTArray object. 508 /// </summary> 509 /// <param name="nodes">List of Nodes.</param> 510 /// <returns>AST Node tree.</returns> make(ASTArray nodes)511 public virtual AST make(ASTArray nodes) 512 { 513 return make(nodes.array); 514 } 515 516 /// <summary> 517 /// Make an AST the root of current AST. 518 /// </summary> 519 /// <param name="currentAST"></param> 520 /// <param name="root"></param> makeASTRoot(ref ASTPair currentAST, AST root)521 public virtual void makeASTRoot(ref ASTPair currentAST, AST root) 522 { 523 if (root != null) 524 { 525 // Add the current root as a child of new root 526 root.addChild(currentAST.root); 527 // The new current child is the last sibling of the old root 528 currentAST.child = currentAST.root; 529 currentAST.advanceChildToEnd(); 530 // Set the new root 531 currentAST.root = root; 532 } 533 } 534 535 /// <summary> 536 /// Sets the global default AST Node Type for this ASTFactory instance. 537 /// This method also attempts to load the <see cref="System.Type"/> instance 538 /// for the specified typename. 539 /// </summary> 540 /// <param name="t">Fully qualified AST Node Type name.</param> setASTNodeType(string t)541 public virtual void setASTNodeType(string t) 542 { 543 if (defaultCreator_ != null) 544 { 545 if (t != defaultCreator_.ASTNodeTypeName) 546 { 547 defaultCreator_ = null; 548 } 549 } 550 defaultASTNodeTypeObject_ = loadNodeTypeObject(t); 551 } 552 553 /// <summary> 554 /// To change where error messages go, can subclass/override this method 555 /// and then setASTFactory in Parser and TreeParser. This method removes 556 /// a prior dependency on class antlr.Tool. 557 /// </summary> 558 /// <param name="e"></param> error(string e)559 public virtual void error(string e) 560 { 561 Console.Error.WriteLine(e); 562 } 563 564 //--------------------------------------------------------------------- 565 // PRIVATE FUNCTION MEMBERS 566 //--------------------------------------------------------------------- 567 loadNodeTypeObject(string nodeTypeName)568 private static Type loadNodeTypeObject(string nodeTypeName) 569 { 570 Type nodeTypeObject = null; 571 bool typeCreated = false; 572 573 if (nodeTypeName != null) 574 { 575 foreach (Assembly assem in AppDomain.CurrentDomain.GetAssemblies()) 576 { 577 try 578 { 579 nodeTypeObject = assem.GetType(nodeTypeName); 580 if (nodeTypeObject != null) 581 { 582 typeCreated = true; 583 break; 584 } 585 } 586 catch 587 { 588 typeCreated = false; 589 } 590 } 591 } 592 if (!typeCreated) 593 { 594 throw new TypeLoadException("Unable to load AST Node Type: '" + nodeTypeName + "'"); 595 } 596 return nodeTypeObject; 597 } 598 createFromAST(AST node)599 private AST createFromAST(AST node) 600 { 601 AST newNode = null; 602 Type nodeAsTypeObj = node.GetType(); 603 604 ASTNodeCreator creator = (ASTNodeCreator) typename2creator_[nodeAsTypeObj.FullName]; 605 if (creator != null) 606 { 607 newNode = creator.Create(); 608 if (newNode == null) 609 { 610 throw new ArgumentException("Unable to create AST Node Type: '" + nodeAsTypeObj.FullName + "'"); 611 } 612 } 613 else 614 { 615 newNode = createFromNodeTypeObject(nodeAsTypeObj); 616 } 617 return newNode; 618 } 619 createFromNodeName(string nodeTypeName)620 private AST createFromNodeName(string nodeTypeName) 621 { 622 AST newNode = null; 623 624 ASTNodeCreator creator = (ASTNodeCreator) typename2creator_[nodeTypeName]; 625 if (creator != null) 626 { 627 newNode = creator.Create(); 628 if (newNode == null) 629 { 630 throw new ArgumentException("Unable to create AST Node Type: '" + nodeTypeName + "'"); 631 } 632 } 633 else 634 { 635 newNode = createFromNodeTypeObject( loadNodeTypeObject(nodeTypeName) ); 636 } 637 return newNode; 638 } 639 createFromNodeType(int nodeTypeIndex)640 private AST createFromNodeType(int nodeTypeIndex) 641 { 642 Debug.Assert((nodeTypeIndex >= 0) && (nodeTypeIndex <= heteroList_.Length), "Invalid AST node type!"); 643 AST newNode = null; 644 645 FactoryEntry entry = heteroList_[nodeTypeIndex]; 646 if ((entry != null) && (entry.Creator != null)) 647 { 648 newNode = entry.Creator.Create(); 649 } 650 else 651 { 652 if ((entry == null) || (entry.NodeTypeObject == null)) 653 { 654 if (defaultCreator_ == null) 655 { 656 newNode = createFromNodeTypeObject(defaultASTNodeTypeObject_); 657 } 658 else 659 newNode = defaultCreator_.Create(); 660 } 661 else 662 newNode = createFromNodeTypeObject( entry.NodeTypeObject ); 663 } 664 return newNode; 665 } 666 createFromNodeTypeObject(Type nodeTypeObject)667 private AST createFromNodeTypeObject(Type nodeTypeObject) 668 { 669 AST newNode = null; 670 671 try 672 { 673 newNode = (AST) Activator.CreateInstance(nodeTypeObject); 674 if (newNode == null) 675 { 676 throw new ArgumentException("Unable to create AST Node Type: '" + nodeTypeObject.FullName + "'"); 677 } 678 } 679 catch(Exception ex) 680 { 681 throw new ArgumentException("Unable to create AST Node Type: '" + nodeTypeObject.FullName + "'", ex); 682 } 683 return newNode; 684 } 685 686 protected class FactoryEntry 687 { FactoryEntry(Type typeObj, ASTNodeCreator creator)688 public FactoryEntry(Type typeObj, ASTNodeCreator creator) 689 { 690 NodeTypeObject = typeObj; 691 Creator = creator; 692 } 693 FactoryEntry(Type typeObj)694 public FactoryEntry(Type typeObj) 695 { 696 NodeTypeObject = typeObj; 697 } 698 FactoryEntry(ASTNodeCreator creator)699 public FactoryEntry(ASTNodeCreator creator) 700 { 701 Creator = creator; 702 } 703 704 public Type NodeTypeObject; 705 public ASTNodeCreator Creator; 706 } 707 } 708 }