示例#1
0
 public Node Clone()
 {
     Node n = new Node();
     n.Attributes = Attributes;
     n.Value = Value;
     n.Left = Left;
     n.Right = Right;
     return n;
 }
示例#2
0
        /// <summary>
        /// Removes any empty child nodes of the specified node
        /// </summary>
        private void RemoveRecursive(Node node)
        {
            if (node.Left != null)
            {
                node.Left.RemoveEmptyChildren();

                if (node.Left.IsEmpty())
                    node.Left = null;
            }

            if (node.Right != null)
            {
                node.Right.RemoveEmptyChildren();

                if (node.Right.IsEmpty())
                    node.Right = null;
            }
        }
示例#3
0
        public void Print(Node node, String dash)
        {
            Console.Write("\n" + dash + "-> " + node.Value);

            String attributes = "";

            if (node.Attributes[0] != "")
                attributes += " " + node.Attributes[0] + ",";
            if (node.Attributes[1] != "")
                attributes += " " + node.Attributes[1] + ",";
            if (node.Attributes[2] != "")
                attributes += " " + node.Attributes[2] + ",";

            if (node.Left != null)
                node.Left.Print(node.Left, dash + "-");
            if (node.Right != null)
                node.Right.Print(node.Right, dash + "-");
        }
示例#4
0
        private void ParseBlock(ref Node node)
        {
            //A block is a number of statements enclosed in {...}
            if (CurrentToken.Value.Equals("{"))
            {
                //Each block starts a new scope
                Database.NewScope();
                NextToken();

                ParseStatements(ref node);

                if (!CurrentToken.Value.Equals("}"))
                    Error("Expected ending of the block: }", CurrentToken.LineStart);

                Database.ParentScope();
            }
            //Or it can just be a single statement
            else
                ParseStatement(ref node);
        }
示例#5
0
        private void ParseAssign(ref Node node)
        {
            node = new Node();
            node.Value = "ASSIGN";
            node.Left = new Node();

            //Parse the variable
            Int32 type = ParseVariableFactor(ref node.Left);

            node.Attributes[2] = Database.GetTypeName(type);

            //Assignment statement must be followed by an equal sign
            if (CurrentToken.Value != "=")
                Error("Expected assignment operator: =", CurrentToken.LineStart);

            NextToken();

            //Expression is on the right child
            Int32 exprType = ParseExpression(ref node.Right, 0);

            //Check type match between variable and expression
            if (!Database.CheckTypesAreEqual(exprType, type))
                Error("Assignment types mismatched", CurrentToken.LineStart);
        }
示例#6
0
        private void ParseVariableDeclaration(ref Node node)
        {
            VariableInfo var = new VariableInfo();

            ParseDeclaration(ref var);

            node = new Node();
            node.Value = "DECLARE";

            node.Attributes[0] = Database.GetVarId(var.Name, null);
            node.Attributes[1] = Database.GetTypeName(var.Type);
        }
示例#7
0
        private void ParseStatements(ref Node node)
        {
            if (CurrentToken.Value.Equals("}"))
                return;

            node = new Node();
            node.Value = "STATEMENT";

            if (!CurrentToken.Value.Equals(";"))
                ParseStatement(ref node.Left);

            //if (!CurrentToken.Value.Equals(";"))
                //Error("Expected semicolon", CurrentToken.LineStart);

            NextToken();
            ParseStatements(ref node.Right);
        }
示例#8
0
 private void ParseStatement(ref Node node)
 {
     //Check the first token to determine what to do
     if (CurrentToken.Value.Equals("IF"))
         ParseIf(ref node);
     else if (CurrentToken.Value.Equals("WHILE"))
         ParseWhile(ref node);
     else if (CurrentToken.Value.Equals("RETURN"))
         ParseReturn(ref node);
     else if (Database.CheckType(CurrentToken.Value))
         ParseVariableDeclaration(ref node);
     else if (CheckAssignComing())
         ParseAssign(ref node);
     else
         ParseFactorEx(ref node);//Error("Unknown statement", CurrentToken.LineStart);
 }
示例#9
0
        private void ParseReturn(ref Node node)
        {
            node = new Node();
            node.Value = "RETURN";

            NextToken();

            if (RetType != Database.GetType("VOID"))
            {
                if (!Database.CheckTypesAreEqual(ParseExpression(ref node.Right, 0), RetType))
                {
                    Error("Return and function types mistmatched", CurrentToken.LineStart);
                }
            }
        }
示例#10
0
        private void ParseIf(ref Node node)
        {
            node = new Node();
            node.Value = "IF";

            NextToken();

            if (!CurrentToken.Value.Equals("("))
                Error("Enclose the condition in (...)", CurrentToken.LineStart);

            NextToken();

            if (ParseExpression(ref node.Left, 0) != Database.GetType("BOOL"))
                Error("IF expressions must be boolean in type", CurrentToken.LineStart);

            if (!CurrentToken.Value.Equals(")"))
                Error("Enclose the condition in (...)", CurrentToken.LineStart);

            NextToken();

            ParseBlock(ref node.Right);

            //If followed by an else statement, parse the else tree
            //Node's value is else
            //If -> Else If then left and right are both if trees
            //If -> Else, left child is previous IF tree and right child is the series of else statements
            NextToken();
            if (CurrentToken.Value.Equals("ELSE"))
            {
                NextToken();
                NextToken();
                Node temp = node;
                node.Left = new Node();
                node.Left = temp;
                node.Value = "ELSE";

                if (CurrentToken.Value.Equals("IF"))
                    ParseIf(ref node.Right);
                else
                    ParseBlock(ref node.Right);
            }
        }
示例#11
0
        private void ParseFunctionsDefinitions(ref Node node)
        {
            RetType = -1;
            Node currentNode;

            Boolean firstFunc = true;

            ResetToken();

                while (CurrentToken.LineStart != Int32.MaxValue)
                {
                    if (CheckFunctionIncoming())
                    {
                        Database.NewScope();

                        if (firstFunc)
                        {
                            node = new Node();
                            currentNode = node;
                            firstFunc = false;
                        }
                        else
                        {
                            node.Right = new Node();
                            node = node.Right;
                        }

                        ParseFunction(ref node);

                        Database.ParentScope();
                    }
                    NextToken();
                }
        }
示例#12
0
        private void ParseFunction(ref Node node)
        {
            RetType = ParseType();

            node.Value = "FUNCTION";
            node.Attributes[0] = CurrentToken.Value;

            Database.AddFunctionToScope(CurrentToken.Value);

            //Skip parameter list - preparser took care of this
            while (!CurrentToken.Value.Equals(")"))
                NextToken();

            NextToken();

            //{ must exist
            if (!CurrentToken.Value.Equals("{"))
                Error("Expected function block {...}", CurrentToken.LineStart);

            NextToken();

            ParseStatements(ref node.Left);

            if (!CurrentToken.Value.Equals("}"))
                Error("Invalid ending: expected '}'", CurrentToken.LineStart);

            NextToken();
        }
示例#13
0
        /// <summary>
        /// Factors can be prefixed or postfixed with unary operators
        /// </summary>
        private Int32 ParseFactorEx(ref Node node)
        {
            //If a pre-unary operator exists
            if (Database.CheckUnaryOperator(CurrentToken.Value, true))
            {
                node = new Node();
                node.Value = CurrentToken.Value;
                node.Attributes[0] = "UNARY_OPERATOR";
                NextToken();

                Int32 type = ParseFactorEx(ref node.Right);
                node.Attributes[2] = Database.GetTypeName(Database.GetReturnType(node.Value, type, true));
                return Database.GetType(node.Attributes[2]);
            }

            //No more pre-operators, parse the actual factor
            ParseFactor(ref node);

            //Check for post-unary operators
            while (Database.CheckUnaryOperator(CurrentToken.Value, false))
            {
                Node temp;
                temp = node;
                node.Left = new Node();
                node.Left = temp;

                node.Value = CurrentToken.Value;
                node.Attributes[0] = "UNARY_OPERATOR";
                NextToken();

                Int32 type = Database.GetReturnType(node.Value,
                                                    Database.GetType(node.Left.Attributes[2]),
                                                    false);

                node.Attributes[2] = Database.GetTypeName(type);
            }

            return Database.GetType(node.Attributes[2]);
        }
示例#14
0
        private Int32 ParseFactor(ref Node node)
        {
            //A factor can be an expression in brackets
            if (CurrentToken.Value.Equals("("))
            {
                if (CurrentToken.Value.Equals("("))
                    NextToken();

                Int32 type = ParseExpression(ref node, 0);

                if (!CurrentToken.Value.Equals(")"))
                    Error("Expected ending parenthesis: )", CurrentToken.LineStart);
                NextToken();

                //A bracketed expression can also have a member
                if (CurrentToken.Value.Equals("."))
                    type = ParseMember(ref node, type);

                return type;
            }

            node = new Node();

            if (CurrentToken.Type.Equals(TokenType.String))
            {
                node.Value = CurrentToken.Value;
                node.Attributes[0] = "VALUE";
                node.Attributes[2] = "STRING";
                NextToken();
                return Database.GetType(node.Attributes[2]);
            }
            else if (CurrentToken.Type.Equals(TokenType.Number))
            {
                node.Value = CurrentToken.Value;
                node.Attributes[0] = "VALUE";
                if (CurrentToken.Value.Contains('.'))
                    node.Attributes[2] = "DOUBLE";
                else
                    node.Attributes[2] = "INT";
                NextToken();
                return Database.GetType(node.Attributes[2]);
            }
            else if (CurrentToken.Type.Equals(TokenType.Character))
            {
                node.Value = CurrentToken.Value;
                node.Attributes[0] = "VALUE";
                node.Attributes[2] = "CHAR";
                NextToken();
                return Database.GetType(node.Attributes[2]);
            }
            else if (CurrentToken.Value.Equals("TRUE") || CurrentToken.Value.Equals("FALSE"))
            {
                node.Value = CurrentToken.Value;
                node.Attributes[0] = "VALUE";
                node.Attributes[2] = "BOOL";
                NextToken();
                return Database.GetType(node.Attributes[2]);
            }
            else if (Database.CheckFunction(CurrentToken.Value))
            {
                node.Value = CurrentToken.Value;
                NextToken();

                if (!CurrentToken.Value.Equals("("))
                    Error("Expected parameters list for function: " + CurrentToken.Value,
                          CurrentToken.LineStart);
                NextToken();

                if (Database.GetParameterNumber(node.Value) != 0)
                    ParseParameters(ref node.Right, node.Value, 0);

                if (!CurrentToken.Value.Equals(")"))
                    Error("Expected ending parenthesis: )", CurrentToken.LineStart);
                NextToken();

                node.Attributes[0] = "FUNCTION";
                node.Attributes[2] = Database.GetTypeName(Database.GetFunctionType(node.Value));

                return Database.GetType(node.Attributes[2]);
            }
            else
                return ParseVariableFactor(ref node);

            return -1;
        }
示例#15
0
        private Int32 ParseVariableFactor(ref Node node)
        {
            //Not an identifier or variable name
            if (!CurrentToken.Type.Equals(TokenType.Identifier))
                Error("Invalid factor", CurrentToken.LineStart, CurrentToken.CharacterPosition);

            if (!Database.CheckVariable(CurrentToken.Value))
                Error("Invalid variable name", CurrentToken.LineStart, CurrentToken.CharacterPosition);

            //The node's value is the variable's unique ID, the factor type is the variable's data type
            node.Value = Database.GetVarId(CurrentToken.Value, null);
            Int32 type = Database.GetVarType(CurrentToken.Value, null);
            node.Attributes[0] = "VARIABLE";
            node.Attributes[2] = Database.GetTypeName(type);
            NextToken();

            //A . means a member is incoming
            if (CurrentToken.Value.Equals("."))
                type = ParseMember(ref node, type);

            return type;
        }
示例#16
0
        private Int32 ParseMember(ref Node node, Int32 type)
        {
            //The node's value is MEMBER, the left is the parent factor, right the member
            Node current = node;
            node.Left = new Node();
            node.Right = new Node();
            node.Left = current;
            node.Value = "MEMBER";
            node.Attributes[0] = String.Empty;

            //Check if it is a valid member and get the data type
            NextToken();

            if (!Database.CheckMember(type, CurrentToken.Value))
                Error("Invalid member", CurrentToken.LineStart, CurrentToken.CharacterPosition);

            Int32 memberType = Database.GetMemberType(type, CurrentToken.Value);

            //The right value is the member's name
            node.Right.Value = CurrentToken.Value;

            NextToken();

            //Check if another type is incoming
            if (CurrentToken.Value.Equals("."))
                memberType = ParseMember(ref node.Right, memberType);

            node.Attributes[2] = Database.GetTypeName(memberType);

            return memberType;
        }
示例#17
0
        private void ParseWhile(ref Node node)
        {
            node = new Node();
            node.Value = "WHILE";

            NextToken();

            if (!CurrentToken.Value.Equals("("))
                Error("Enclose the condition in (...)", CurrentToken.LineStart);

            NextToken();

            if (ParseExpression(ref node.Left, 0) != Database.GetType("BOOL"))
                Error("Expression must be a boolean in the while", CurrentToken.LineStart);

            if (!CurrentToken.Value.Equals(")"))
                Error("Enclose the condition in (...)", CurrentToken.LineStart);

            NextToken();

            ParseBlock(ref node.Right);
        }
示例#18
0
        private void ParseParameters(ref Node node, String functionName, Int32 parameterIndex)
        {
            //If end of parameter parsing
            if (CurrentToken.Value.Equals(")"))
                return;

            node = new Node();
            node.Value = "PARAMETER";

            //Parse the expression in the node's left child
            Int32 type = ParseExpression(ref node.Left, 0);

            //Check if the types of the expression and parameter match
            if (!Database.CheckTypesAreEqual(type,
                                             Database.GetParameterType(functionName, parameterIndex)))
                Error("Invalid parameter type", CurrentToken.LineStart, CurrentToken.CharacterPosition);

            //This parameter has been parsed, now check for future parameters
            if (parameterIndex != Database.GetParameterNumber(functionName) - 1)
            {
                //Two parameters must be separated by a comma
                if (!CurrentToken.Value.Equals(","))
                    Error("Expected comma to separate more parameters", CurrentToken.LineStart);

                NextToken();

                if (CurrentToken.Value.Equals(")"))
                    Error("Expected more parameters", CurrentToken.LineStart);

                ParseParameters(ref node.Right, functionName, parameterIndex + 1);
            }
        }
示例#19
0
        private Int32 ParseExpression(ref Node node, int precedenceLevel)
        {
            Int32 type = ParseFactor(ref node);

            if (Database.CheckOperator(CurrentToken.Value))
            {
                if (node == null)
                    node = new Node();

                Node clonedNode = node.Clone();
                node.Left = clonedNode;
                node.Value = CurrentToken.Value;

                NextToken();

                ParseFactor(ref node.Right);
            }

            return type;

            /*
            //If we have reached over the maximum precedence level, we need to parse a factor
            if (precedenceLevel > MaxPrecedenceLevel)
                return ParseFactorEx(ref node);

            //Parse another expression of higher precedence and set it to LType
            Int32 lType = ParseExpression(ref node, precedenceLevel+1);

            Int32 temporaryToken;

            //Check if an operator of current precedence level exists
            while (Database.CheckOperator(CurrentToken.Value, precedenceLevel))
            {
                //An operator exists but it may not be what we want, mark the token in case we want
                //to return to it
                temporaryToken = TokenIndex;

                //Then the operator is the node and the previously parsed expression is the left child node
                String op = CurrentToken.Value;

                Node temp;
                temp = node;
                node.Left = new Node();
                node.Left = temp.Clone();

                node.Value = op;
                node.Attributes[0] = "OPERATOR";
                NextToken();

                //Right child node is the other expression of high precedence level
                Int32 rType = ParseExpression(ref node.Right, precedenceLevel + 1);

                //Return type retrieved from database
                Int32 retType = Database.GetReturnType(op, lType, rType, precedenceLevel);

                //Catch here
                //If retType == -1 then the operator with LType, RType and Precedence level DO NOT exist
                //There may exist an operator with such LType and RType but a different precedence level
                //do not match
                //In such case, we parsed the operator in the wrong precedence level
                //We have to reset the previously saved token's position and also the expression tree
                if (retType.Equals(-1))
                {
                    node.Right = null;
                    node = temp;
                    TokenIndex = temporaryToken;
                    CurrentToken = Tokens[TokenIndex];
                    break;
                }

                //Valid return type is the type of the expression
                node.Attributes[2] = Database.GetTypeName(retType);
                lType = retType;
            }

            return lType;
             * */
        }
示例#20
0
 public Node()
 {
     Left = Right = null;
     Attributes[0] = Attributes[1] = Attributes[2] = Value = String.Empty;
 }