/// <summary> /// While There are more functions to parse /// </summary> /// <returns></returns> public TModule ParseFunctions() { while (Current_Token == TOKEN.TOK_FUNCTION) { ProcedureBuilder b = ParseFunction(); Procedure s = b.GetProcedure(); if (s == null) { Console.WriteLine("Error While Parsing Functions"); return(null); } prog.Add(s); GetNext(); } // // Convert the builder into a program // return(prog.GetProgram()); }
/// <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> /// /// </summary> /// <returns></returns> public TModule DoParse() { try { ProcedureBuilder p = new ProcedureBuilder("MAIN", new COMPILATION_CONTEXT()); ArrayList stmts = Parse(p); foreach (Stmt s in stmts) { p.AddStatement(s); } Procedure pc = p.GetProcedure(); prog.Add(pc); return(prog.GetProgram()); } catch (Exception e) { Console.WriteLine(e.ToString()); return(null); } }
/// <summary> /// <Expr> ::= <Term> | <Term> { + | - } <Expr> /// /// </summary> /// <returns></returns> public Exp Expr(ProcedureBuilder ctx) { TOKEN l_token; Exp RetValue = Term(ctx); while (Current_Token == TOKEN.TOK_PLUS || Current_Token == TOKEN.TOK_SUB) { l_token = Current_Token; Current_Token = GetToken(); Exp e1 = Expr(ctx); if (l_token == TOKEN.TOK_PLUS) { RetValue = new BinaryPlus(RetValue, e1); } else { RetValue = new BinaryMinus(RetValue, e1); } } return(RetValue); }
/// <summary> /// <Term> ::= <Factor> | <Factor> {*|/} <Term> /// </summary> public Exp Term(ProcedureBuilder ctx) { TOKEN l_token; Exp RetValue = Factor(ctx); while (Current_Token == TOKEN.TOK_MUL || Current_Token == TOKEN.TOK_DIV) { l_token = Current_Token; Current_Token = GetToken(); Exp e1 = Term(ctx); if (l_token == TOKEN.TOK_MUL) { RetValue = new Mul(RetValue, e1); } else { RetValue = new Div(RetValue, e1); } } return(RetValue); }
/// <summary> /// Parse A Single Function. /// </summary> /// <returns></returns> ProcedureBuilder ParseFunction() { // // Create a Procedure builder Object // ProcedureBuilder p = new ProcedureBuilder("", new COMPILATION_CONTEXT()); if (Current_Token != TOKEN.TOK_FUNCTION) { return(null); } GetNext(); // return type of the Procedure ought to be // Boolean , Numeric or String if (!(Current_Token == TOKEN.TOK_VAR_BOOL || Current_Token == TOKEN.TOK_VAR_NUMBER || Current_Token == TOKEN.TOK_VAR_STRING)) { return(null); } //-------- Assign the return type p.TYPE = (Current_Token == TOKEN.TOK_VAR_BOOL) ? TYPE_INFO.TYPE_BOOL : (Current_Token == TOKEN.TOK_VAR_NUMBER) ? TYPE_INFO.TYPE_NUMERIC : TYPE_INFO.TYPE_STRING; // Parse the name of the Function call GetNext(); if (Current_Token != TOKEN.TOK_UNQUOTED_STRING) { return(null); } p.Name = this.last_str; // assign the name // ---------- Opening parenthesis for // the start of <paramlist> GetNext(); if (Current_Token != TOKEN.TOK_OPAREN) { return(null); } //---- Parse the Formal Parameter list FormalParameters(p); if (Current_Token != TOKEN.TOK_CPAREN) { return(null); } GetNext(); // --------- Parse the Function code ArrayList lst = StatementList(p); if (Current_Token != TOKEN.TOK_END) { throw new Exception("END expected"); } // Accumulate all statements to // Procedure builder // foreach (Stmt s in lst) { p.AddStatement(s); } return(p); }
/// <summary> /// /// </summary> /// <param name="pb"></param> /// <param name="p"></param> /// <returns></returns> public Exp ParseCallProc(ProcedureBuilder pb, Procedure p) { GetNext(); if (Current_Token != TOKEN.TOK_OPAREN) { throw new Exception("Opening Parenthesis expected"); } GetNext(); ArrayList actualparams = new ArrayList(); while (true) { // Evaluate Each Expression in the // parameter list and populate actualparams // list Exp exp = BExpr(pb); // do type analysis exp.TypeCheck(pb.Context); // if , there are more parameters if (Current_Token == TOKEN.TOK_COMMA) { actualparams.Add(exp); GetNext(); continue; } if (Current_Token != TOKEN.TOK_CPAREN) { throw new Exception("Expected paranthesis"); } else { // Add the last parameters actualparams.Add(exp); break; } } // if p is null , that means it is a // recursive call. Being a one pass // compiler , we need to wait till // the parse process to be over to // resolve the Procedure. // // if (p != null) { return(new CallExp(p, actualparams)); } else { return(new CallExp(pb.Name, true, // recurse ! actualparams)); } }
/// <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 Exception(); } 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 Exception("Undefined symbol"); } GetNext(); return(new Variable(inf)); } // // 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 Exception(); } return(RetValue); }
/// <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> /// This Routine Queries Statement Type /// to take the appropriate Branch... /// Currently , only Print and PrintLine statement /// are supported.. /// if a line does not start with Print or PrintLine .. /// an exception is thrown /// </summary> /// <returns></returns> private Stmt Statement(ProcedureBuilder ctx) { Stmt retval = null; switch (Current_Token) { case TOKEN.TOK_VAR_STRING: case TOKEN.TOK_VAR_NUMBER: case TOKEN.TOK_VAR_BOOL: retval = ParseVariableDeclStatement(ctx); GetNext(); return(retval); case TOKEN.TOK_ARRAY: retval = ParseArrayDeclStatement(ctx); GetNext(); return(retval); case TOKEN.TOK_MAP: retval = ParseMapDeclStatement(ctx); GetNext(); return(retval); case TOKEN.TOK_PRINT: retval = ParsePrintStatement(ctx); GetNext(); break; case TOKEN.TOK_PRINTLN: retval = ParsePrintLNStatement(ctx); GetNext(); break; case TOKEN.TOK_UNQUOTED_STRING: { if (!prog.IsFunction(base.last_str)) { retval = ParseAssignmentStatement(ctx); GetNext(); return(retval); } else { Exp ex = BExpr(ctx); retval = new ExpStmt(ex); GetNext(); return(retval); } } case TOKEN.TOK_IF: retval = ParseIfStatement(ctx); GetNext(); return(retval); case TOKEN.TOK_WHILE: retval = ParseWhileStatement(ctx); GetNext(); return(retval); case TOKEN.TOK_RETURN: retval = ParseReturnStatement(ctx); GetNext(); return(retval); default: throw new CParserException(-1, "Invalid statement", SaveIndex()); } return(retval); }
/// <summary> /// Parse A Single Function. /// </summary> /// <returns></returns> protected ProcedureBuilder ParseFunction() { // // Create a Procedure builder Object // ProcedureBuilder p = new ProcedureBuilder("", new COMPILATION_CONTEXT()); if (Current_Token != TOKEN.TOK_FUNCTION) { throw new CParserException(-1, "FUNCTION expected ", SaveIndex()); } GetNext(); // return type of the Procedure ought to be // Boolean , Numeric or String if (!(Current_Token == TOKEN.TOK_VAR_BOOL || Current_Token == TOKEN.TOK_VAR_NUMBER || Current_Token == TOKEN.TOK_VAR_STRING || Current_Token == TOKEN.TOK_ARRAY || Current_Token == TOKEN.TOK_MAP)) { throw new CParserException(-1, "A Legal data type expected ", SaveIndex()); } if (Current_Token == TOKEN.TOK_MAP || Current_Token == TOKEN.TOK_ARRAY) { throw new CParserException(-1, "Array / Map not supported as return value", SaveIndex()); } else { //-------- Assign the return type p.TYPE = (Current_Token == TOKEN.TOK_VAR_BOOL) ? TYPE_INFO.TYPE_BOOL : (Current_Token == TOKEN.TOK_VAR_NUMBER) ? TYPE_INFO.TYPE_NUMERIC : TYPE_INFO.TYPE_STRING; } // Parse the name of the Function call GetNext(); if (Current_Token != TOKEN.TOK_UNQUOTED_STRING) { throw new CParserException(-1, "Function name expected ", SaveIndex()); } p.Name = this.last_str; // assign the name // ---------- Opening parenthesis for // the start of <paramlist> GetNext(); if (Current_Token != TOKEN.TOK_OPAREN) { throw new CParserException(-1, "Opening Parenthesis expected", SaveIndex()); } //---- Parse the Formal Parameter list FormalParameters(p); if (Current_Token != TOKEN.TOK_CPAREN) { throw new CParserException(-1, "Closing Parenthesis expected", SaveIndex()); } GetNext(); // --------- Parse the Function code ArrayList lst = StatementList(p); if (Current_Token != TOKEN.TOK_END) { throw new CParserException(-1, "END expected", SaveIndex()); } // Accumulate all statements to // Procedure builder // foreach (Stmt s in lst) { p.AddStatement(s); } return(p); }
/// <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); }
/// <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 = Expr(ctx); // Recurse if (Current_Token != TOKEN.TOK_CPAREN) { Console.WriteLine("Missing Closing Parenthesis\n"); throw new Exception(); } 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_UNQUOTED_STRING) { /// /// Variables /// String str = base.last_str; SYMBOL_INFO inf = ctx.TABLE.Get(str); if (inf == null) { throw new Exception("Undefined symbol"); } GetNext(); RetValue = new Variable(inf); } else { Console.WriteLine("Illegal Token"); throw new Exception(); } return(RetValue); }