Esempio n. 1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="pb"></param>
        /// <returns></returns>
        public Stmt ParseWhileStatement(ProcedureBuilder pb)
        {
            GetNext();

            Exp exp = BExpr(pb);

            if (pb.TypeCheck(exp) != TYPE_INFO.TYPE_BOOL)
            {
                throw new Exception("Expects a boolean expression");
            }

            ArrayList body = StatementList(pb);

            if ((Current_Token != TOKEN.TOK_WEND))
            {
                CSyntaxErrorLog.AddLine("Wend Expected");
                CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                throw new CParserException(-100, "Wend Expected", SaveIndex());
            }


            return(new WhileStatement(exp, body));
        }
        /// <summary>
        ///    Parse the Assignment Statement
        ///    <variable> = <expr>
        /// </summary>
        /// <param name="pb"></param>
        /// <returns></returns>
        public Stmt ParseAssignmentStatement(ProcedureBuilder ctx)
        {
            //
            // Retrieve the variable and look it up in
            // the symbol table ..if not found throw exception
            //
            string      variable         = base.last_str;
            SYMBOL_INFO s                = ctx.TABLE.Get(variable);
            Exp         index_expression = null;

            if (s == null)
            {
                CSyntaxErrorLog.AddLine("Variable not found  " + last_str);
                CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                throw new CParserException(-100, "Variable not found", SaveIndex());
            }


            if (s.Type == TYPE_INFO.TYPE_ARRAY || s.Type == TYPE_INFO.TYPE_MAP)
            {
                GetNext();

                if (Current_Token != TOKEN.TOK_OSUBSCRIPT)
                {
                    CSyntaxErrorLog.AddLine("[ expected ");
                    CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                    throw new CParserException(-100, "[ expected ", SaveIndex());
                }

                GetNext();
                Exp a = BExpr(ctx);
                //
                // Do the type analysis ...
                //
                TYPE_INFO tp = a.TypeCheck(ctx.Context);

                if (s.Type == TYPE_INFO.TYPE_MAP)
                {
                    if (tp != s.m_info.key)
                    {
                        CSyntaxErrorLog.AddLine("Type mismatch in key ");
                        CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                        throw new CParserException(-100, "Type mismatch in key ", SaveIndex());
                    }
                }
                else
                {
                    if (tp != s.a_info.tf)
                    {
                        CSyntaxErrorLog.AddLine("Type mismatch in index ");
                        CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                        throw new CParserException(-100, "Type mismatch in index ", SaveIndex());
                    }
                }

                index_expression = a;

                if (Current_Token != TOKEN.TOK_CSUBSCRIPT)
                {
                    throw new CParserException(-100, "] is expected", SaveIndex());
                }
            }

            //------------ The next token ought to be an assignment
            // expression....



            GetNext();

            if (Current_Token != TOKEN.TOK_ASSIGN)
            {
                CSyntaxErrorLog.AddLine("= expected");
                CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                throw new CParserException(-100, "= expected", SaveIndex());
            }

            //-------- Skip the token to start the expression
            // parsing on the RHS
            GetNext();
            Exp exp = BExpr(ctx);

            //------------ Do the type analysis ...
            if (s.Type == TYPE_INFO.TYPE_BOOL || s.Type == TYPE_INFO.TYPE_NUMERIC ||
                s.Type == TYPE_INFO.TYPE_STRING)
            {
                if (exp.TypeCheck(ctx.Context) != s.Type)
                {
                    throw new CParserException(-1, "Type mismatch in assignment", SaveIndex());
                }
            }
            else
            {
                exp.TypeCheck(ctx.Context);
            }

            // -------------- End of statement ( ; ) is expected
            if (Current_Token != TOKEN.TOK_SEMI)
            {
                CSyntaxErrorLog.AddLine("; expected");
                CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                throw new CParserException(-100, " ; expected", SaveIndex());
            }
            // return an instance of AssignmentStatement node..
            //   s => Symbol info associated with variable
            //   exp => to evaluated and assigned to symbol_info
            if (index_expression == null)
            {
                return(new AssignmentStatement(s, exp));
            }
            else
            {
                return(new AssignmentStatement(s, index_expression, exp));
            }
        }
        /// <summary>
        ///     <Factor>::=  <number> | ( <expr> ) | {+|-} <factor>
        ///           <variable> | TRUE | FALSE
        /// </summary>
        public Exp Factor(ProcedureBuilder ctx)
        {
            TOKEN l_token;
            Exp   RetValue = null;



            if (Current_Token == TOKEN.TOK_NUMERIC)
            {
                RetValue      = new NumericConstant(GetNumber());
                Current_Token = GetToken();
            }
            else if (Current_Token == TOKEN.TOK_STRING)
            {
                RetValue      = new StringLiteral(last_str);
                Current_Token = GetToken();
            }
            else if (Current_Token == TOKEN.TOK_BOOL_FALSE ||
                     Current_Token == TOKEN.TOK_BOOL_TRUE)
            {
                RetValue = new BooleanConstant(
                    Current_Token == TOKEN.TOK_BOOL_TRUE ? true : false);
                Current_Token = GetToken();
            }
            else if (Current_Token == TOKEN.TOK_OPAREN)
            {
                Current_Token = GetToken();

                RetValue = BExpr(ctx);  // Recurse

                if (Current_Token != TOKEN.TOK_CPAREN)
                {
                    Console.WriteLine("Missing Closing Parenthesis\n");
                    throw new CParserException(-100, "Missing Closing Parenthesis\n", SaveIndex());
                }
                Current_Token = GetToken();
            }

            else if (Current_Token == TOKEN.TOK_PLUS || Current_Token == TOKEN.TOK_SUB)
            {
                l_token       = Current_Token;
                Current_Token = GetToken();
                RetValue      = Factor(ctx);
                if (l_token == TOKEN.TOK_PLUS)
                {
                    RetValue = new UnaryPlus(RetValue);
                }
                else
                {
                    RetValue = new UnaryMinus(RetValue);
                }
            }
            else if (Current_Token == TOKEN.TOK_NOT)
            {
                l_token       = Current_Token;
                Current_Token = GetToken();
                RetValue      = Factor(ctx);

                RetValue = new LogicalNot(RetValue);
            }
            else if (Current_Token == TOKEN.TOK_UNQUOTED_STRING)
            {
                String str = base.last_str;


                if (!prog.IsFunction(str))
                {
                    //
                    // if it is not a function..it ought to
                    // be a variable...
                    SYMBOL_INFO inf = ctx.GetSymbol(str);

                    if (inf == null)
                    {
                        throw new CParserException(-100, "Undefined symbol " + str, SaveIndex());
                    }

                    if (inf.Type != TYPE_INFO.TYPE_ARRAY &&
                        inf.Type != TYPE_INFO.TYPE_MAP)
                    {
                        GetNext();
                        return(new Variable(inf));
                    }

                    if (inf.Type == TYPE_INFO.TYPE_ARRAY)
                    {
                        GetNext();
                        if (Current_Token != TOKEN.TOK_OSUBSCRIPT)
                        {
                            CSyntaxErrorLog.AddLine("[ expected");
                            CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                            throw new CParserException(-100, "[ expected", SaveIndex());
                        }
                        GetNext();
                        Exp index = BExpr(ctx);
                        if (Current_Token != TOKEN.TOK_CSUBSCRIPT)
                        {
                            CSyntaxErrorLog.AddLine("] expected");
                            CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                            throw new CParserException(-100, "] expected", SaveIndex());
                        }

                        GetNext();
                        return(new IndexedExp(new IndexedVariable(inf, index, null)));
                    }
                    else
                    {
                        GetNext();

                        if (Current_Token != TOKEN.TOK_OSUBSCRIPT)
                        {
                            CSyntaxErrorLog.AddLine("[ expected");
                            CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                            throw new CParserException(-100, "[ expected", SaveIndex());
                        }
                        GetNext();
                        Exp index = BExpr(ctx);

                        if (Current_Token != TOKEN.TOK_CSUBSCRIPT)
                        {
                            CSyntaxErrorLog.AddLine("] expected");
                            CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                            throw new CParserException(-100, "] expected", SaveIndex());
                        }

                        GetNext();
                        return(new HashExp(new HashedVariable(inf, index, null)));
                    }
                }

                //
                // P can be null , if we are parsing a
                // recursive function call
                //
                Procedure p = prog.GetProc(str);
                // It is a Function Call
                // Parse the function invocation
                //
                Exp ptr = ParseCallProc(ctx, p);
                GetNext();
                return(ptr);
            }



            else
            {
                //Console.WriteLine("Illegal Token");
                throw new CParserException(-100, "Illegal Token", SaveIndex());
            }


            return(RetValue);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="pb"></param>
        /// <returns></returns>
        public Stmt ParseMapDeclStatement(ProcedureBuilder pb)
        {
            MAP_INFO t_info = new MAP_INFO();


            GetNext();

            if (Current_Token != TOKEN.TOK_LT)
            {
                CSyntaxErrorLog.AddLine("< expected");
                CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                throw new CParserException(-100, " < expected", -1);
            }

            GetNext();

            if (!(Current_Token == TOKEN.TOK_VAR_BOOL ||
                  Current_Token == TOKEN.TOK_VAR_NUMBER ||
                  Current_Token == TOKEN.TOK_VAR_STRING))
            {
                CSyntaxErrorLog.AddLine(" expects a data type ");
                CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                throw new CParserException(-100, " expects a data type", -1);
            }
            TOKEN tok = Current_Token;

            t_info.key = (Current_Token == TOKEN.TOK_VAR_BOOL) ?
                         TYPE_INFO.TYPE_BOOL : (Current_Token == TOKEN.TOK_VAR_NUMBER) ?
                         TYPE_INFO.TYPE_NUMERIC : TYPE_INFO.TYPE_STRING;

            GetNext();

            if (Current_Token != TOKEN.TOK_COMMA)
            {
                CSyntaxErrorLog.AddLine(" expects a ,");
                CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                throw new CParserException(-100, " expects a ,", -1);
            }
            GetNext();

            if (!(Current_Token == TOKEN.TOK_VAR_BOOL ||
                  Current_Token == TOKEN.TOK_VAR_NUMBER ||
                  Current_Token == TOKEN.TOK_VAR_STRING))
            {
                CSyntaxErrorLog.AddLine(" expects a data type ");
                CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                throw new CParserException(-100, " expects a data type", -1);
            }
            TOKEN tok1 = Current_Token;

            t_info.Value = (Current_Token == TOKEN.TOK_VAR_BOOL) ?
                           TYPE_INFO.TYPE_BOOL : (Current_Token == TOKEN.TOK_VAR_NUMBER) ?
                           TYPE_INFO.TYPE_NUMERIC : TYPE_INFO.TYPE_STRING;



            GetNext();

            if (Current_Token != TOKEN.TOK_GT)
            {
                CSyntaxErrorLog.AddLine(" expects a >");
                CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                throw new CParserException(-100, " expects a >", -1);
            }


            // --- Skip to the next token , the token ought
            // to be a Variable name ( UnQouted String )
            GetNext();

            if (Current_Token == TOKEN.TOK_UNQUOTED_STRING)
            {
                SYMBOL_INFO symb = new SYMBOL_INFO();
                symb.SymbolName = base.last_str;

                if (pb.TABLE.Get(base.last_str) != null)
                {
                    CSyntaxErrorLog.AddLine(" duplicate symbol");
                    CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                    throw new CParserException(-100, " duplicate symbol", -1);
                }

                symb.Type         = TYPE_INFO.TYPE_MAP;
                symb.m_info       = new MAP_INFO();
                symb.m_info.key   = t_info.key;
                symb.m_info.Value = t_info.Value;

                Type basetype = null;



                symb.m_info.data = new Hashtable();

                //---------- Skip to Expect the SemiColon

                GetNext();

                if (Current_Token == TOKEN.TOK_SEMI)
                {
                    // ----------- Add to the Symbol Table
                    // for type analysis
                    pb.TABLE.Add(symb);

                    // --------- return the Object of type
                    // --------- VariableDeclStatement
                    // This will just store the Variable name
                    // to be looked up in the above table
                    return(new VariableDeclStatement(symb));
                }
                else
                {
                    CSyntaxErrorLog.AddLine("; expected");
                    CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                    throw new CParserException(-100, ", or ; expected", SaveIndex());
                }
            }

            return(null);
        }
        public Stmt ParseArrayDeclStatement(ProcedureBuilder pb)
        {
            ARRAY_INFO t_info = new ARRAY_INFO();


            GetNext();

            if (Current_Token != TOKEN.TOK_LT)
            {
                CSyntaxErrorLog.AddLine("< expected");
                CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                throw new CParserException(-100, " < expected", -1);
            }

            GetNext();

            if (!(Current_Token == TOKEN.TOK_VAR_BOOL ||
                  Current_Token == TOKEN.TOK_VAR_NUMBER ||
                  Current_Token == TOKEN.TOK_VAR_STRING))
            {
                CSyntaxErrorLog.AddLine(" expects a data type ");
                CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                throw new CParserException(-100, " expects a data type", -1);
            }
            TOKEN tok = Current_Token;

            t_info.tf = (Current_Token == TOKEN.TOK_VAR_BOOL) ?
                        TYPE_INFO.TYPE_BOOL : (Current_Token == TOKEN.TOK_VAR_NUMBER) ?
                        TYPE_INFO.TYPE_NUMERIC : TYPE_INFO.TYPE_STRING;

            GetNext();

            if (Current_Token != TOKEN.TOK_COMMA)
            {
                CSyntaxErrorLog.AddLine(" expects a ,");
                CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                throw new CParserException(-100, " expects a ,", -1);
            }
            GetNext();



            if (Current_Token != TOKEN.TOK_NUMERIC)
            {
                CSyntaxErrorLog.AddLine(" expects a array bound");
                CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                throw new CParserException(-100, " expects a array bound", -1);
            }

            double limits = base.GetNumber();

            GetNext();

            if (Current_Token != TOKEN.TOK_GT)
            {
                CSyntaxErrorLog.AddLine(" expects a >");
                CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                throw new CParserException(-100, " expects a >", -1);
            }


            // --- Skip to the next token , the token ought
            // to be a Variable name ( UnQouted String )
            GetNext();

            if (Current_Token == TOKEN.TOK_UNQUOTED_STRING)
            {
                SYMBOL_INFO symb = new SYMBOL_INFO();
                symb.SymbolName = base.last_str;

                if (pb.TABLE.Get(base.last_str) != null)
                {
                    CSyntaxErrorLog.AddLine(" duplicate symbol");
                    CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                    throw new CParserException(-100, " duplicate symbol", -1);
                }

                symb.Type      = TYPE_INFO.TYPE_ARRAY;
                symb.a_info    = new ARRAY_INFO();
                symb.a_info.tf = (tok == TOKEN.TOK_VAR_BOOL) ?
                                 TYPE_INFO.TYPE_BOOL : (tok == TOKEN.TOK_VAR_NUMBER) ?
                                 TYPE_INFO.TYPE_NUMERIC : TYPE_INFO.TYPE_STRING;
                symb.a_info.bound = (int)limits;
                Type basetype = null;

                basetype                       = (tok == TOKEN.TOK_VAR_BOOL) ?
                                      basetype = typeof(Boolean) :
                                                 (tok == TOKEN.TOK_VAR_NUMBER) ?
                                                 typeof(Double) : typeof(String);

                symb.a_info.data = Array.CreateInstance(basetype, (int)limits);

                //---------- Skip to Expect the SemiColon

                GetNext();

                if (Current_Token == TOKEN.TOK_SEMI)
                {
                    // ----------- Add to the Symbol Table
                    // for type analysis
                    pb.TABLE.Add(symb);

                    // --------- return the Object of type
                    // --------- VariableDeclStatement
                    // This will just store the Variable name
                    // to be looked up in the above table
                    return(new VariableDeclStatement(symb));
                }
                else
                {
                    CSyntaxErrorLog.AddLine("; expected");
                    CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                    throw new CParserException(-100, ", or ; expected", SaveIndex());
                }
            }

            return(null);
        }