/// <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); }