예제 #1
0
        /// <summary>
        /// Parse
        /// </summary>
        /// <returns>Base block</returns>
        public Block Parse()
        {
            Block baseBlock = new Block(null), actualBlock = baseBlock;

            int level = 0;

            while (HasNextToken())
            {
                #region Class Parsing

                if (Match(TokenType.CLASS))
                {
                    Token classToken = Pop();
                    if (Match(TokenType.IDENTIFIER))
                    {
                        Token nameToken = Pop();
                        actualBlock.AddBlock(actualBlock = new Class(actualBlock, nameToken.Value));
                        level++;
                    }
                    else
                        Logger.Error("You must specify a name for your class.");
                }

                #endregion

                #region Method declaration parsing

                else if (Match(TokenType.FUNCTION))
                {
                    Token methodToken = Pop();
                    if (Match(TokenType.IDENTIFIER))
                    {
                        Token nameToken = Pop();

                        if (Match(TokenType.OPENPAREN))
                        {
                            Pop(); // Pop the open parenthesis

                            List<Parameter> parameters = new List<Parameter>();

                            while (true)
                            {
                                if (MatchOneOfThem(new TokenType[] { TokenType.BOOL, TokenType.INT, TokenType.STRING, TokenType.FLOAT, TokenType.IDENTIFIER }))
                                {
                                    TokenType argType = Pop().Type;
                                    if (Match(TokenType.IDENTIFIER))
                                    {
                                        string argName = Pop().Value;
                                        parameters.Add(new Parameter((VariableType)argType, argName));
                                        if (Match(TokenType.COMMA))
                                        {
                                            Pop(); // Pop the comma
                                            continue;
                                        }
                                        else
                                            break;
                                    }
                                    else
                                        Logger.Error("You need to set a name for your parameter");
                                }
                                else
                                    break;
                            }

                            if (!Match(TokenType.CLOSEPAREN))
                                Logger.Error("You need to close parenthesis after put parameters");
                            else
                                Pop(); // Pop the parenthesis

                            TokenType returnType = TokenType.UNKNOWN;

                            if (Match(TokenType.RETURN))
                            {
                                Pop(); // Pop the return keyword
                                if (!MatchOneOfThem(new TokenType[] { TokenType.BOOL, TokenType.IDENTIFIER, TokenType.INT, TokenType.STRING, TokenType.FLOAT, TokenType.VOID }))
                                    Logger.Error("Wrong return type for your function");
                                else
                                    returnType = Pop().Type;
                            }
                            else
                                Logger.Error("You need to set return type");

                            actualBlock.AddBlock(actualBlock = new Method(actualBlock, nameToken.Value, (VariableType)returnType, parameters.ToArray()));
                            level++;
                        }
                        else
                            Logger.Error("You need to open parenthesis for function declaration.");
                    }
                    else
                        Logger.Error("You must specify a name for your method.");
                }

                #endregion

                #region Constructor parsing

                else if (Match(TokenType.CONSTRUCTOR))
                {
                    Token constructorToken = Pop();

                    if (Match(TokenType.OPENPAREN))
                    {
                        Pop();
                        List<Parameter> parameters = new List<Parameter>();
                        while (true)
                        {
                            if (MatchOneOfThem(new TokenType[] { TokenType.BOOL, TokenType.INT, TokenType.STRING, TokenType.FLOAT, TokenType.IDENTIFIER }))
                            {
                                Token argType = Pop();
                                if (Match(TokenType.IDENTIFIER))
                                {
                                    string argName = Pop().Value;
                                    if ((VariableType)argType.Type == VariableType.CUSTOM)
                                        parameters.Add(new Parameter((VariableType)argType.Type, argName, argType.Value));
                                    else
                                        parameters.Add(new Parameter((VariableType)argType.Type, argName));
                                    if (Match(TokenType.COMMA))
                                    {
                                        Pop(); // Pop the comma
                                        continue;
                                    }
                                    else
                                        break;
                                }
                                else
                                    Logger.Error("You need to set a name for your parameter");
                            }
                            else
                                break;
                        }
                        if (!Match(TokenType.CLOSEPAREN))
                            Logger.Error("You need to close parenthesis after put parameters");
                        else
                            Pop(); // Pop the parenthesis
                        actualBlock.AddBlock(actualBlock = new Constructor(actualBlock, parameters.ToArray()));
                        level++;
                    }
                    else
                        Logger.Error("You need to open parenthesis after constructor.");
                }

                #endregion

                #region Variable declaration parsing

                else if (MatchOneOfThem(new TokenType[] { TokenType.BOOL, TokenType.STRING, TokenType.INT, TokenType.FLOAT }))
                {
                    if (actualBlock.GetType() == typeof(Block))
                        Logger.Error("Variable can only be delcared inside a class, function...");

                    Token typeToken = Pop();
                    if (Match(TokenType.IDENTIFIER))
                    {
                        Token nameToken = Pop();
                        actualBlock.AddBlock(new VariableDeclarationStatement(actualBlock, nameToken.Value, (VariableType)typeToken.Type));

                        if (Match(TokenType.ASSIGN))
                        {
                            Pop(); // Pop the assign char
                            actualBlock.AddBlock(new AssignStatement(actualBlock, nameToken.Value, AssignType.EQUAL, Exp(actualBlock)));
                        }
                    }
                    else
                        Logger.Error("You must specify a name for your variable.");
                }

                #endregion

                #region Identifier parsing -> Custom object declaration, method call ...

                else if (Match(TokenType.IDENTIFIER))
                {
                    Token identifierToken = Pop();
                    if (Match(TokenType.IDENTIFIER)) // Custom object declaration
                    {
                        Token nameToken = Pop();
                        actualBlock.AddBlock(new VariableDeclarationStatement(actualBlock, nameToken.Value, VariableType.CUSTOM, identifierToken.Value));

                        if (Match(TokenType.ASSIGN))
                        {
                            Pop(); // Pop the assign char
                            actualBlock.AddBlock(new AssignStatement(actualBlock, nameToken.Value, AssignType.EQUAL, Exp(actualBlock)));
                        }
                    }
                    else if (Match(TokenType.ASSIGN))
                    {
                        Pop(); // Pop the assign char
                        actualBlock.AddBlock(new AssignStatement(actualBlock, identifierToken.Value, AssignType.EQUAL, Exp(actualBlock)));
                    }
                }

                #endregion

                #region Condition parsing

                else if (Match(TokenType.IF))
                {
                    Pop(); // Pop the if keyword
                    if (Match(TokenType.OPENPAREN))
                    {
                        Pop(); // Pop the paren
                        List<IExpression> leftExp = Exp(actualBlock);
                        if (MatchOneOfThem(new TokenType[] { TokenType.DIFFERENT, TokenType.EQUAL, TokenType.GREATER, TokenType.GREATEREQUAL, TokenType.LESS, TokenType.LESSEQUAL }))
                        {
                            Token compToken = Pop();
                            List<IExpression> rightExp = Exp(actualBlock);
                            if (Match(TokenType.CLOSEPAREN))
                            {
                                Pop(); // Pop the paren
                                actualBlock.AddBlock(actualBlock = new ConditionStatement(actualBlock, leftExp, rightExp, compToken.Type));
                                level++;
                            }
                            else
                                Logger.Error("You need to close parenthesis after if condition");
                        }
                        else
                            Logger.Error("Wrong comparison operator for if");
                    }
                    else
                        Logger.Error("You must open parenthesis after if keyword");
                }

                else if (Match(TokenType.ELSE))
                {
                    if (!(actualBlock is ConditionStatement) && !(actualBlock is ElseIfStatement))
                        Logger.Error("Cant declare else statement without if before.");

                    Pop(); // Pop the else keyword
                    if (Match(TokenType.IF))
                    {
                        Pop(); // Pop the if keyword
                        if (Match(TokenType.OPENPAREN))
                        {
                            Pop(); // Pop the paren
                            List<IExpression> leftExp = Exp(actualBlock);
                            if (MatchOneOfThem(new TokenType[] { TokenType.DIFFERENT, TokenType.EQUAL, TokenType.GREATER, TokenType.GREATEREQUAL, TokenType.LESS, TokenType.LESSEQUAL }))
                            {
                                Token compToken = Pop();
                                List<IExpression> rightExp = Exp(actualBlock);
                                if (Match(TokenType.CLOSEPAREN))
                                {
                                    Pop(); // Pop the paren
                                    if (actualBlock is ElseIfStatement)
                                        actualBlock = actualBlock.SuperBlock;
                                    actualBlock.AddBlock(actualBlock = new ElseIfStatement(actualBlock, leftExp, rightExp, compToken.Type));
                                }
                                else
                                    Logger.Error("You need to close parenthesis after else if condition");
                            }
                            else
                                Logger.Error("Wrong comparison operator for else if");
                        }
                        else
                            Logger.Error("You must open parenthesis after else if keyword");
                    }
                    else
                    {
                        if (actualBlock is ElseIfStatement)
                            actualBlock = actualBlock.SuperBlock;
                        actualBlock.AddBlock(actualBlock = new ElseStatement(actualBlock));
                    }
                }

                #endregion

                #region Print parsing

                else if (Match(TokenType.PRINT))
                {
                    Pop(); // Pop print
                    if (Match(TokenType.OPENPAREN))
                    {
                        Pop(); // Pop parenthesis
                        actualBlock.AddBlock(new PrintStatement(actualBlock, Exp(actualBlock)));

                        if (!Match(TokenType.CLOSEPAREN))
                            Logger.Error("You need to close parenthesis after function call");
                        else
                            Pop(); // Pop parenthesis
                    }
                }

                #endregion

                #region Return parsing

                else if (Match(TokenType.RETURN))
                {
                    Pop(); // Pop the return keyword
                    actualBlock.AddBlock(new ReturnStatement(actualBlock, Exp(actualBlock)));
                }

                #endregion

                #region End parsing

                else if (Match(TokenType.END))
                {
                    Pop(); // Pop the end keyword
                    if (actualBlock is ElseStatement || actualBlock is ElseIfStatement)
                        actualBlock = actualBlock.SuperBlock;
                    level--;
                    if (level < 0)
                        Logger.Error("Useful end");
                    actualBlock = actualBlock.SuperBlock;
                }

                #endregion

                else
                    Pop();

                //TODO FINISH PARSER
            }

            return baseBlock;
        }
예제 #2
0
 /// <summary>
 /// Main constructor
 /// </summary>
 /// <param name="superBlock">Super block</param>
 /// <param name="parameters">Parameters</param>
 public Constructor(Block superBlock, Parameter[] parameters) : base(superBlock)
 {
     Parameters = parameters;
     if (superBlock is Class)
         ClassBlock = superBlock as Class;
 }