예제 #1
0
        /// <summary>
        /// 对某个AST节点求值,并打印求值过程
        /// </summary>
        /// <param name="node"></param>
        /// <param name="indent">打印输出时的缩进量,用tab控制</param>
        /// <returns></returns>
        private int Evaluate(ASTNode node, string indent)
        {
            int result = 0;

            Console.WriteLine(indent + "Calculating:" + node.GetType());
            switch (node.GetType())
            {
            case ASTNodeType.Program:
                foreach (ASTNode child in node.GetChildren())
                {
                    result = Evaluate(child, indent + "\t");
                }
                break;

            case ASTNodeType.Additive:
                ASTNode child1 = node.GetChildren()[0];
                int     value1 = Evaluate(child1, indent + "\t");
                ASTNode child2 = node.GetChildren()[1];
                int     value2 = Evaluate(child2, indent + "\t");
                if (node.GetText().Equals("+"))
                {
                    result = value1 + value2;
                }
                else
                {
                    result = value1 - value2;
                }
                break;

            case ASTNodeType.Multiplicative:
                child1 = node.GetChildren()[0];
                value1 = Evaluate(child1, indent + "\t");
                child2 = node.GetChildren()[1];
                value2 = Evaluate(child2, indent + "\t");
                if (node.GetText().Equals("*"))
                {
                    result = value1 * value2;
                }
                else
                {
                    result = value1 / value2;
                }
                break;

            case ASTNodeType.IntLiteral:
                result = int.Parse(node.GetText());
                break;

            default:
                break;
            }
            Console.WriteLine(indent + "Result:" + result);
            return(result);
        }
예제 #2
0
        public void FlattenExpression_Assignment_MemoryValue_Both()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "x"));
            var additionnode = new AdditionNode(new MemoryValueNode(100), new MemoryValueNode(100));
            var assignment   = new VariableAssignmentNode("x", additionnode);

            ast.AddChild(assignment);

            var changes = FlattenExpression(ast, 1);

            Assert.IsTrue(changes > 0);
            var children = ast.GetChildren().ToList();

            Assert.AreEqual(6, children.Count);
            Assert.IsInstanceOfType(additionnode.Left, typeof(VariableValueNode));
            Assert.IsInstanceOfType(additionnode.Right, typeof(VariableValueNode));
            Assert.IsInstanceOfType(children[0], typeof(VariableDeclarationNode));
            Assert.IsInstanceOfType(children[1], typeof(VariableDeclarationNode));
            Assert.IsInstanceOfType(children[2], typeof(VariableAssignmentNode));
            Assert.IsInstanceOfType(children[3], typeof(VariableDeclarationNode));
            Assert.IsInstanceOfType(children[4], typeof(VariableAssignmentNode));
            Assert.IsInstanceOfType(children[5], typeof(VariableAssignmentNode));
            Assert.AreSame(children[5], assignment);
            Assert.AreNotEqual(((VariableAssignmentNode)children[2]).VariableName, ((VariableAssignmentNode)children[4]).VariableName);
        }
예제 #3
0
        public void FlattenExpression_Assignment_SideSubexpressionExtracted()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "x"));
            ast.AddChild(new VariableAssignmentNode("x", new SubtractionNode(
                                                        new AdditionNode(
                                                            new ShortValueNode(1),
                                                            new ShortValueNode(2)
                                                            ),
                                                        new AdditionNode(
                                                            new ShortValueNode(3),
                                                            new ShortValueNode(4)
                                                            )
                                                        )));

            var changes = FlattenExpression(ast, 1);

            Assert.IsTrue(changes > 0);
            var children = ast.GetChildren().ToList();

            Assert.AreEqual(6, children.Count);
            Assert.IsInstanceOfType(children[0], typeof(VariableDeclarationNode));
            Assert.IsInstanceOfType(children[1], typeof(VariableDeclarationNode));
            Assert.IsInstanceOfType(children[2], typeof(VariableAssignmentNode));
            Assert.IsInstanceOfType(children[3], typeof(VariableDeclarationNode));
            Assert.IsInstanceOfType(children[4], typeof(VariableAssignmentNode));
            Assert.IsInstanceOfType(children[5], typeof(VariableAssignmentNode));
        }
예제 #4
0
 void dumpAST(ASTNode node, string indent)
 {
     Console.WriteLine(indent + node.GetType() + " " + node.GetText());
     foreach (var child in node.GetChildren())
     {
         dumpAST(child, indent + "\t");
     }
 }
예제 #5
0
        public void RemoveUnusedVariables_DeclaredButNotUsed_Removes()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "a"));

            RemoveUnusedVariables(ast);

            Assert.AreEqual(0, ast.GetChildren().Count());
        }
예제 #6
0
        public void RemoveUnusedVariables_WriteButNoRead_Removes()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "a"));
            ast.AddChild(new VariableAssignmentNode("a", new ShortValueNode(5)));

            RemoveUnusedVariables(ast);

            Assert.AreEqual(0, ast.GetChildren().Count());
        }
예제 #7
0
        public void FindLastUsage_DoesntFind()
        {
            var rootnode = new ASTNode();

            rootnode.AddChild(new VariableDeclarationNode("int", "x"));                     // int x
            rootnode.AddChild(new VariableAssignmentNode("x", new ShortValueNode(5)));      // x = 5
            rootnode.AddChild(new VariableDeclarationNode("int", "y"));                     // int y
            rootnode.AddChild(new VariableAssignmentNode("y", new VariableValueNode("x"))); // y = x
            rootnode.AddChild(new VariableDeclarationNode("int", "z"));                     // int z

            var lastusage = FindLastVariableUsage(rootnode.GetChildren().ToList(), "x", 10);

            Assert.AreEqual(10, lastusage);
        }
예제 #8
0
        public void PropagateConstants_RemovesDecrement_Multiple()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "a"));
            ast.AddChild(new VariableAssignmentNode("a", new ShortValueNode(5)));
            ast.AddChild(new DecrementNode("a"));
            ast.AddChild(new DecrementNode("a"));
            ast.AddChild(new DecrementNode("a"));
            ast.AddChild(new DecrementNode("a"));

            PropagateConstants(ast);

            Assert.AreEqual(2, ast.GetChildren().Count());
        }
예제 #9
0
        public void TestCheckSyntax()
        {
            Token        tmpToken;
            LineContext  tmpContext;
            List <Token> tokens = new List <Token>();

            tmpToken       = new Token(Global.DataType.IDENTIFIER);
            tmpToken.value = "print";
            tokens.Add(tmpToken);
            tmpToken = new Token(Global.DataType.OPEN_ROUND_BRACKET);
            tokens.Add(tmpToken);
            tmpToken       = new Token(Global.DataType.STRING);
            tmpToken.value = "\"hoi\"";
            tokens.Add(tmpToken);
            tmpToken = new Token(Global.DataType.CLOSE_ROUND_BRACKET);
            tokens.Add(tmpToken);

            List <LineContext> context = new List <LineContext>();

            tmpContext = new LineContext(1, 1);
            context.Add(tmpContext);
            tmpContext = new LineContext(1, 1);
            context.Add(tmpContext);
            tmpContext = new LineContext(1, 1);
            context.Add(tmpContext);
            tmpContext = new LineContext(1, 1);
            context.Add(tmpContext);

            SyntaxAnalyzer syntaxAnalyer = new SyntaxAnalyzer();
            ASTNode        result        = syntaxAnalyer.CheckSyntax(tokens, context);

            Assert.AreEqual(Global.ASTType.BASE, result.GetType());
            Assert.AreEqual(Global.ASTType.FUNCTION_CALL, result.GetChildren()[0].GetType());
            Assert.AreEqual("print", result.GetChildren()[0].GetName());
            Assert.AreEqual("\"hoi\"", result.GetChildren()[0].GetChildren()[0].GetName());
        }
예제 #10
0
        public void TransformToIncDec_Subtract_Right_Optimizes()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "x"));
            ast.AddChild(new VariableAssignmentNode("x", new ShortValueNode(0)));
            ast.AddChild(new VariableAssignmentNode("x", new SubtractionNode(new VariableValueNode("x"), new ShortValueNode(1))));

            var changesmade = TransformToIncDec(ast);

            Assert.IsTrue(changesmade);
            var children = ast.GetChildren().ToList();

            Assert.AreEqual(3, children.Count);
            Assert.IsInstanceOfType(children[2], typeof(DecrementNode));
        }
예제 #11
0
        public void PropagateConstants_RemovesDecrement()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "a"));
            ast.AddChild(new VariableAssignmentNode("a", new ShortValueNode(5)));
            ast.AddChild(new DecrementNode("a"));
            ast.AddChild(new VariableDeclarationNode("byte", "b"));
            var assignment = new VariableAssignmentNode("b", new VariableValueNode("a"));

            ast.AddChild(assignment);

            PropagateConstants(ast);

            Assert.IsInstanceOfType(assignment.Value, typeof(ShortValueNode));
            Assert.AreEqual(4, ((ShortValueNode)assignment.Value).GetValue());
            Assert.AreEqual(4, ast.GetChildren().Count());
        }
예제 #12
0
        public void Transform_SubtractionAssignmentToExpression()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "x"));
            ast.AddChild(new SubtractionAssignmentNode("x", new ShortValueNode(5)));

            var changed = TransformSubtractionAssignmentToExpression(ast);

            var children = ast.GetChildren().ToList();

            Assert.IsTrue(changed);
            Assert.AreEqual(2, children.Count);
            Assert.IsInstanceOfType(children[1], typeof(VariableAssignmentNode));
            var assignment = (VariableAssignmentNode)children[1];

            Assert.IsInstanceOfType(assignment.Value, typeof(SubtractionNode));
            Assert.IsInstanceOfType(((SubtractionNode)assignment.Value).Left, typeof(VariableValueNode));
            Assert.IsInstanceOfType(((SubtractionNode)assignment.Value).Right, typeof(ShortValueNode));
        }
예제 #13
0
        public void PropagteConstants_If_ExtractsTrueBody()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "x"));
            ast.AddChild(new VariableAssignmentNode("x", new ShortValueNode(1)));
            var block = new BlockNode();

            block.AddChild(new VariableDeclarationNode("byte", "a"));
            block.AddChild(new VariableAssignmentNode("a", new ShortValueNode(1)));
            ast.AddChild(new IfNode(new VariableValueNode("x"), block));

            var changesmade = PropagateConstants(ast);

            Assert.IsTrue(changesmade);
            var children = ast.GetChildren().ToList();

            Assert.AreEqual(4, children.Count);
            Assert.IsInstanceOfType(children[2], typeof(VariableDeclarationNode));
            Assert.IsInstanceOfType(children[3], typeof(VariableAssignmentNode));
        }
예제 #14
0
        public void FlattenExpresison_Assignment_If_ConditionExtracts()
        {
            var ast    = new ASTNode();
            var ifnode = new IfNode(
                new AdditionNode(
                    new ShortValueNode(0),
                    new ShortValueNode(1)
                    ), new BlockNode()
                );

            ast.AddChild(ifnode);

            var changes = FlattenExpression(ast, 0);

            Assert.IsTrue(changes > 0);
            var children = ast.GetChildren().ToList();

            Assert.AreEqual(3, children.Count);
            Assert.IsInstanceOfType(children[0], typeof(VariableDeclarationNode));
            Assert.IsInstanceOfType(ifnode.Condition, typeof(VariableValueNode));
        }
예제 #15
0
        public void RemoveUnusedVariables_ReducesChain()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "a"));
            ast.AddChild(new VariableAssignmentNode("a", new ShortValueNode(5)));
            ast.AddChild(new VariableDeclarationNode("byte", "b"));
            ast.AddChild(new VariableAssignmentNode("b", new VariableValueNode("a")));
            ast.AddChild(new VariableDeclarationNode("byte", "c"));
            ast.AddChild(new VariableAssignmentNode("c", new VariableValueNode("b")));

            var iterations = 0;

            while (RemoveUnusedVariables(ast))
            {
                iterations++;
            }

            Assert.AreEqual(3, iterations);
            Assert.AreEqual(0, ast.GetChildren().Count());
        }
예제 #16
0
        public void PropagteConstants_If_ExtractsFalseBody()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "x"));
            ast.AddChild(new VariableAssignmentNode("x", new ShortValueNode(0)));
            var iftrue = new BlockNode();

            iftrue.AddChild(new VariableAssignmentNode("x", new ShortValueNode(1)));
            var iffalse = new BlockNode();

            iffalse.AddChild(new AdditionAssignmentNode("x", new ShortValueNode(2)));
            ast.AddChild(new IfNode(new VariableValueNode("x"), iftrue, iffalse));

            var changesmade = PropagateConstants(ast);

            Assert.IsTrue(changesmade);
            var children = ast.GetChildren().ToList();

            Assert.AreEqual(3, children.Count);
            Assert.IsInstanceOfType(children[2], typeof(AdditionAssignmentNode));
        }
예제 #17
0
        private int Evaluate(ASTNode node, string indent)
        {
            int result = 0;

            if (verbose)
            {
                Console.WriteLine(indent + "Calculatings:" + node.GetType());
            }
            switch (node.GetType())
            {
            case ASTNodeType.Program:
                foreach (var child in node.GetChildren())
                {
                    result = Evaluate(child, indent);
                }
                break;

            case ASTNodeType.Additive:
                ASTNode child1 = node.GetChildren()[0];
                int     value1 = Evaluate(child1, indent + "\t");
                ASTNode child2 = node.GetChildren()[1];
                int     value2 = Evaluate(child2, indent + "\t");
                if (node.GetText().Equals("+"))
                {
                    result = value1 + value2;
                }
                else
                {
                    result = value1 - value2;
                }
                break;

            case ASTNodeType.Multiplicative:
                child1 = node.GetChildren()[0];
                value1 = Evaluate(child1, indent + "\t");
                child2 = node.GetChildren()[1];
                value2 = Evaluate(child2, indent + "\t");
                if (node.GetText().Equals("*"))
                {
                    result = value1 * value2;
                }
                else
                {
                    result = value1 / value2;
                }
                break;

            case ASTNodeType.IntLiteral:
                result = int.Parse(node.GetText());
                break;

            case ASTNodeType.Identifier:
                string varName = node.GetText();
                if (variables.ContainsKey(varName))
                {
                    int value;
                    if (!variables.TryGetValue(varName, out value))
                    {
                        throw new Exception("variables " + varName + "has not been set any value");
                    }
                }
                else
                {
                    throw new Exception("unknow variable:" + varName);
                }
                break;

            case ASTNodeType.AssignmentStmt:
                varName = node.GetText();
                if (!variables.ContainsKey(varName))
                {
                }
            }
        }