void Process(Node targetNode, Queue<Token> tokenQueue, TreeBuilderState state) { state.ProcessingState = new ProcessingState(targetNode, tokenQueue); while (tokenQueue.Any()) { var token = tokenQueue.Dequeue(); var tokenType = token.Type; var rule = rules .Where(r => r.TokenType == tokenType) .FirstOrDefault(); if (rule == null) { targetNode.AddChild(new ParseFailureNode(token, "unexpected token")); break; } var node = rule.NodeBuilder(token, state); if (node != null) targetNode.AddChild(node); } }
public void TreeBuilder_AssignIdsToNodes_ShouldAssignIdsByLevel() { // Arrange var nodes = new Node[] { new LiteralNode("1", 0), // 1 new GroupNode("(23(45)67)", 1, // 2 new LiteralNode("23", 2), // 4 new GroupNode("(45)", 4, // 5 new LiteralNode("45", 5)), // 7 new LiteralNode("67", 8)), // 6 new LiteralNode("8", 11), // 3 }; // Act TreeBuilder.AssignIdsToNodes(nodes); // Assert CollectionAssert.AreEqual(new Node[] { new LiteralNode("1", 0) { NodeId = 1 }, new GroupNode("(23(45)67)", 1, new LiteralNode("23", 2) { NodeId = 4 }, new GroupNode("(45)", 4, new LiteralNode("45", 5) { NodeId = 7 }) { NodeId = 5 }, new LiteralNode("67", 8) { NodeId = 6 }) { NodeId = 2 }, new LiteralNode("8", 11) { NodeId = 3 }, }, nodes.ToArray() ); }
public QuantifierNode(string data, int startIndex, int? min, int? max, Node child) : base(data, startIndex) { this.min = min; this.max = max; AddChild(child); }
public virtual bool Equals(Node other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; return Equals(other.data, data) && other.startIndex == startIndex && other.NodeId == NodeId && other.children.SequenceEqual(children); }
internal static string BuildNodeClass(Node currentNode) { var nodeClasses = new List<string> { "ast-node", "ast-node-" + currentNode.NodeId }; if (currentNode is ParseFailureNode) nodeClasses.Add("ast-parse-failure-node"); return string.Join(" ", nodeClasses.Where(n => !string.IsNullOrEmpty(n)).ToArray()); }
public override bool Equals(Node other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; return base.Equals(other) && Equals(((ParseFailureNode)other).message, message); }
public ProcessingState(Node targetNode, Queue<Token> tokens) { this.targetNode = targetNode; this.tokens = tokens; }
public void AddChild(Node node) { children.Add(node); }
internal static IHtmlString RenderExpressionAsHtml(Node rootNode) { var markupBuilder = new StringBuilder(); var nodes = rootNode.Children; var nodesToProcess = new Stack<Node>(nodes.Reverse()); var layers = new Stack<int>(new[] { nodes.Count() }); var layerNodes = new Stack<Node>(new[] { rootNode }); var nodeToParentDictionary = nodes.ToDictionary(n => n, p => rootNode); while (nodesToProcess.Any()) { var layersToClose = 0; while (layers.Any() && layers.Peek() == 0) { layersToClose++; layers.Pop(); } layers.Push(layers.Pop() - 1); for (var i = 0; i < layersToClose; i++) { RenderTrailingDataForNode(markupBuilder, layerNodes.Pop()); markupBuilder.Append("</span>"); } var currentNode = nodesToProcess.Pop(); RenderDataBetweenThisAndPreviousNode(markupBuilder, currentNode, nodeToParentDictionary); markupBuilder.AppendFormat( "<span class=\"{0}\" title=\"{1}\">", BuildNodeClass(currentNode), HttpUtility.HtmlAttributeEncode(currentNode.Description)); if (currentNode.Children.Any()) { layers.Push(currentNode.Children.Count()); layerNodes.Push(currentNode); foreach (var childNode in currentNode.Children.Reverse()) { nodesToProcess.Push(childNode); nodeToParentDictionary[childNode] = currentNode; } } else { markupBuilder.Append(HttpUtility.HtmlEncode(currentNode.Data)); markupBuilder.Append("</span>"); } } for (var i = 0; i < layers.Count(); i++) { RenderTrailingDataForNode(markupBuilder, layerNodes.Pop()); var isLastLayer = i == layers.Count() - 1; if (!isLastLayer) markupBuilder.Append("</span>"); } return new HtmlString(markupBuilder.ToString()); }
static void RenderTrailingDataForNode(StringBuilder markupBuilder, Node currentNode) { if (!currentNode.Children.Any()) return; var lastChild = currentNode.Children.Last(); var lastChildEndIndex = lastChild.StartIndex - currentNode.StartIndex + lastChild.Data.Length; var trailingCharacters = currentNode.Data.Substring(lastChildEndIndex); markupBuilder.Append(HttpUtility.HtmlEncode(trailingCharacters)); }
static void RenderDataBetweenThisAndPreviousNode(StringBuilder markupBuilder, Node currentNode, IDictionary<Node, Node> nodeToParentDictionary) { var parentNode = nodeToParentDictionary[currentNode]; if (parentNode == null) return; var indexOfCurrentNodeAtThisLevel = parentNode.Children.ToList().IndexOf(currentNode); if (indexOfCurrentNodeAtThisLevel == 0) { if (currentNode.StartIndex == 0) return; var charactersBeforeThisFirstNode = parentNode.Data.Substring(0, currentNode.StartIndex - parentNode.StartIndex); markupBuilder.Append(HttpUtility.HtmlEncode(charactersBeforeThisFirstNode)); } else { var previousNodeAtThisLevel = parentNode.Children.ElementAt(indexOfCurrentNodeAtThisLevel - 1); var endIndexOfPreviousNodeAtThisLevel = previousNodeAtThisLevel.StartIndex + previousNodeAtThisLevel.Data.Length; var numberOfCharactersBetweenPreviousAndCurrentNode = currentNode.StartIndex - endIndexOfPreviousNodeAtThisLevel; if (numberOfCharactersBetweenPreviousAndCurrentNode <= 0) return; var charactersBetweenPreviousAndCurrentNode = parentNode.Data.Substring(endIndexOfPreviousNodeAtThisLevel, numberOfCharactersBetweenPreviousAndCurrentNode); markupBuilder.Append(HttpUtility.HtmlEncode(charactersBetweenPreviousAndCurrentNode)); } }
public NodeViewModel(Node node) { this.node = node; }