public void Init() { _testTree = new ParseNode(ParseEnum.Start); _testTree.AddChild(new ParseNode(ParseEnum.Expression)); _testTree.GetChildren()[0].AddChild(new ParseNode(ParseEnum.Term)); _testTree.GetChildren()[0].AddChild(new ParseNode(ParseEnum.ExpressionAccent)); ParseNode node = _testTree.GetChildren()[0].GetChildren()[0]; node.AddChild(new ParseNode(ParseEnum.Factor)); node.AddChild(new ParseNode(ParseEnum.TermAccent)); node.GetChildren()[0].AddChild(new ParseNode(ParseEnum.Number, "3")); node.GetChildren()[1].AddChild(new ParseNode(ParseEnum.Empty)); node = _testTree.GetChildren()[0].GetChildren()[1]; node.AddChild(new ParseNode(ParseEnum.Operator, "+")); node.AddChild(new ParseNode(ParseEnum.Term)); node.AddChild(new ParseNode(ParseEnum.ExpressionAccent)); ParseNode termNode = node.GetChildren()[1]; termNode.AddChild(new ParseNode(ParseEnum.Factor)); termNode.AddChild(new ParseNode(ParseEnum.TermAccent)); termNode.GetChildren()[0].AddChild(new ParseNode(ParseEnum.Number, "4")); termNode.GetChildren()[1].AddChild(new ParseNode(ParseEnum.Empty)); node.GetChildren()[2].AddChild(new ParseNode(ParseEnum.Empty)); }
private void Expacc() { _currentNode.AddChild(new ParseNode(ParseEnum.ExpressionAccent)); _currentNode = _currentNode.GetChildren()[_currentNode.GetChildren().Count - 1]; if (_current is AddSub) { _currentNode.AddChild(new ParseNode(ParseEnum.Operator, _current.GetValue())); if (!_lex.EndOfInput) { _current = _lex.GetNextToken(); } Term(); Expacc(); } else if (_current is Equals) { _currentNode.AddChild(new ParseNode(ParseEnum.Equals)); if (!_lex.EndOfInput) { _current = _lex.GetNextToken(); } Expressie(); } else { _currentNode.AddChild(new ParseNode(ParseEnum.Empty)); } _currentNode = _currentNode.GetParent(); }
private void Expressie() { _currentNode.AddChild(new ParseNode(ParseEnum.Expression)); _currentNode = _currentNode.GetChildren()[_currentNode.GetChildren().Count - 1]; Term(); Expacc(); _currentNode = _currentNode.GetParent(); }
/// <summary> /// Generates a Queue by walking breadth first through the tree. /// </summary> /// <param name="node">Starting node</param> /// <returns>Queue in breadth first order</returns> public List<ParseNode> GetBreadthFirstQueue(ParseNode node) { List<ParseNode> brQueue = new List<ParseNode>(); Queue<ParseNode> queue = new Queue<ParseNode>(); queue.Enqueue(node); brQueue.Add(node); while (queue.Count > 0) { ParseNode tempNode = queue.Dequeue(); foreach (ParseNode parseNode in tempNode.GetChildren()) { queue.Enqueue(parseNode); brQueue.Add(parseNode); } } return brQueue; }
/// <summary> /// Generates a abstract syntrax tree from the given ParseTree /// </summary> /// <param name="node">Start node</param> /// <returns>Abstract syntax tree </returns> public ASTNode GenerateAST(ParseNode node) { ASTNode root; // Skip start node if (node.GetEnum() == ParseEnum.Start) { node = node.GetChildren()[0]; } List<ParseNode> bfQueue = GetBreadthFirstQueue(node).FindAll(x => x.GetEnum() == ParseEnum.Operator || x.GetEnum() == ParseEnum.Number || x.GetEnum() == ParseEnum.Variable || x.GetEnum() == ParseEnum.Equals); // If there is only one interesting node no further processing needs to be done. if (bfQueue.Count == 1) { root = ConvertPNtoASTNode(bfQueue[0]); } else { // Handle special condition if (bfQueue.Count == 3 && (bfQueue.Find(x => x.GetEnum() == ParseEnum.Operator || x.GetEnum() == ParseEnum.Equals) != null)) { ParseNode op = bfQueue.Find(x => x.GetEnum() == ParseEnum.Operator || x.GetEnum() == ParseEnum.Equals); bfQueue.Remove(op); if (op.GetEnum() == ParseEnum.Equals) { root = new EqualSign(op.GetValue()); } else { root = new Operator(op.GetValue()); } root.LeftChild = ConvertPNtoASTNode(bfQueue[0]); root.RightChild = ConvertPNtoASTNode(bfQueue[1]); } else { // Normal routine // Handles the left and right tree recursivly ParseNode subTree = node.GetChildren().Find(x => ContainsNode(x, bfQueue[0])); root = ConvertPNtoASTNode(bfQueue[0]); if (node.GetChildren()[0].Equals(subTree)) { subTree.GetChildren().Remove(bfQueue[0]); root.LeftChild = GenerateAST(subTree); root.RightChild = GenerateAST(node.GetChildren()[1]); } else { subTree.GetChildren().Remove(bfQueue[0]); root.RightChild = GenerateAST(subTree); root.LeftChild = GenerateAST(node.GetChildren()[0]); } } } return root; }
/// <summary> /// Converts a ParseNode object into it correspondending AST node. Throws an exception when there is no conversion possible. /// </summary> /// <param name="parseNode">Parsenode to be converted</param> /// <returns>AST node</returns> private ASTNode ConvertPNtoASTNode(ParseNode parseNode) { ASTNode ret; switch (parseNode.GetEnum()) { case ParseEnum.Number: ret = new Number(parseNode.GetValue()); break; case ParseEnum.Operator: ret = new Operator(parseNode.GetValue()); break; case ParseEnum.Variable: ret = new Variable(parseNode.GetValue()); break; case ParseEnum.Equals: ret = new EqualSign(parseNode.GetValue()); break; default: throw new Exception("Could not convert Parsenode"); } return ret; }
private bool ContainsNode(ParseNode startNode, ParseNode nodeToFind) { if (startNode.Equals(nodeToFind)) { return true; } return startNode.GetChildren().Exists(x => ContainsNode(x, nodeToFind)); }
private void Factor() { _currentNode.AddChild(new ParseNode(ParseEnum.Factor)); _currentNode = _currentNode.GetChildren()[_currentNode.GetChildren().Count - 1]; if (_current is OpenParenthesis) { _currentNode.AddChild(new ParseNode(ParseEnum.OpenParenthesis)); _current = _lex.GetNextToken(); Expressie(); if (_current is CloseParenthesis) { _currentNode.AddChild(new ParseNode(ParseEnum.CloseParenthesis)); if (!_lex.EndOfInput) { _current = _lex.GetNextToken(); } } } else if (_current is Variable) { _currentNode.AddChild(new ParseNode(ParseEnum.Variable, _current.GetValue())); if (!_lex.EndOfInput) { _current = _lex.GetNextToken(); } } else if (_current is Number) { _currentNode.AddChild(new ParseNode(ParseEnum.Number, _current.GetValue())); if (!_lex.EndOfInput) { _current = _lex.GetNextToken(); } } else { Console.WriteLine("Syntaxfout."); Stop(); } _currentNode = _currentNode.GetParent(); }
public Parser(String invoer) { _lex = new LexicalScanner(invoer); _currentNode = _start; }
private void Termacc() { _currentNode.AddChild(new ParseNode(ParseEnum.TermAccent)); _currentNode = _currentNode.GetChildren()[_currentNode.GetChildren().Count - 1]; if (_current is Operator) { _currentNode.AddChild(new ParseNode(ParseEnum.Operator, _current.GetValue())); if (!_lex.EndOfInput) { _current = _lex.GetNextToken(); } Factor(); Termacc(); } else { _currentNode.AddChild(new ParseNode(ParseEnum.Empty)); } _currentNode = _currentNode.GetParent(); }
private void Term() { _currentNode.AddChild(new ParseNode(ParseEnum.Term)); _currentNode = _currentNode.GetChildren()[_currentNode.GetChildren().Count - 1]; Factor(); Termacc(); _currentNode = _currentNode.GetParent(); }
public void SetParent(ParseNode parent) { this.Parent = parent; }
public void AddChild(ParseNode child) { child.SetParent(this); Children.Add(child); }