예제 #1
0
        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));
        }
예제 #2
0
파일: Parser.cs 프로젝트: TIRKIN/RDP
 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();
 }
예제 #3
0
파일: Parser.cs 프로젝트: TIRKIN/RDP
 private void Expressie()
 {
     _currentNode.AddChild(new ParseNode(ParseEnum.Expression));
     _currentNode = _currentNode.GetChildren()[_currentNode.GetChildren().Count - 1];
     Term();
     Expacc();
     _currentNode = _currentNode.GetParent();
 }
예제 #4
0
        /// <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;
        }
예제 #5
0
        /// <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;
        }
예제 #6
0
        /// <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;
        }
예제 #7
0
        private bool ContainsNode(ParseNode startNode, ParseNode nodeToFind)
        {
            if (startNode.Equals(nodeToFind))
            {
                return true;
            }

            return startNode.GetChildren().Exists(x => ContainsNode(x, nodeToFind));
        }
예제 #8
0
파일: Parser.cs 프로젝트: TIRKIN/RDP
 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();
 }
예제 #9
0
파일: Parser.cs 프로젝트: TIRKIN/RDP
 public Parser(String invoer)
 {
     _lex = new LexicalScanner(invoer);
     _currentNode = _start;
 }
예제 #10
0
파일: Parser.cs 프로젝트: TIRKIN/RDP
 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();
 }
예제 #11
0
파일: Parser.cs 프로젝트: TIRKIN/RDP
 private void Term()
 {
     _currentNode.AddChild(new ParseNode(ParseEnum.Term));
     _currentNode = _currentNode.GetChildren()[_currentNode.GetChildren().Count - 1];
     Factor();
     Termacc();
     _currentNode = _currentNode.GetParent();
 }
예제 #12
0
파일: ParseNode.cs 프로젝트: TIRKIN/RDP
 public void SetParent(ParseNode parent)
 {
     this.Parent = parent;
 }
예제 #13
0
파일: ParseNode.cs 프로젝트: TIRKIN/RDP
 public void AddChild(ParseNode child)
 {
     child.SetParent(this);
     Children.Add(child);
 }