PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/antlr-2.7.5/lib/csharp/src/antlr/ASTFactory.cs

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