/// <summary> /// Create a node when a rule is visited /// </summary> /// <param name="context"></param> public override void EnterEveryRule([NotNull] ParserRuleContext context) { base.EnterEveryRule(context); //create metadata to save some information of context TreeViewerNodeMeta node = new TreeViewerNodeMeta(); node.StartIndex = context.Start.StartIndex; node.StopIndex = context.Stop.StopIndex; //current node is parent of context, add context to child list of current node if (_currentNode.Text == context.Parent?.GetType().Name) { _currentNode.Nodes.Add(context.GetType().Name); _currentNode = _currentNode.Nodes[_currentNode.Nodes.Count - 1]; _currentNode.Tag = node; } else { //current node is root node if (_currentNode.Parent == null) { _currentNode.Nodes.Add(context.GetType().Name); _currentNode = _currentNode.Nodes[_currentNode.Nodes.Count - 1]; _currentNode.Tag = node; } else { //current node and context node is same lever _currentNode.Parent.Nodes.Add(context.GetType().Name); _currentNode = _currentNode.Parent.Nodes[_currentNode.Parent.Nodes.Count - 1]; _currentNode.Tag = node; } } //context is leaf node if (context.ChildCount == 1 && context.GetChild(0).ChildCount <= 0) { node.Token = context.GetText(); _currentNode.Nodes.Add(context.GetText()); _currentNode.Nodes[0].Tag = node; } }
/// <summary> /// Find a node in TreeNode that it's context match token /// </summary> /// <param name="tree"></param> /// <param name="tokenStart"></param> /// <returns></returns> public static TreeNode FindNode(TreeNode tree, int tokenStart) { try { var current = tree; TreeViewerNodeMeta meta = current.Tag as TreeViewerNodeMeta; if ((current.Tag != null) && meta.StartIndex <= tokenStart && meta.StopIndex >= tokenStart && tree.Nodes.Count == 0) { if (current.PrevNode != null) { return(current.PrevNode); } else { return(current.Parent); } } else { TreeNode result; foreach (TreeNode node in current.Nodes) { result = FindNode(node, tokenStart); if (result != null) { return(result); } } return(null); } } catch (Exception ex) { return(null); } }