bool Parser::EPrime() { bool plus = false; if ("+" == lex) { plus = true; L.getTokLex(tok,lex); } else if ("-" == lex) { L.getTokLex(tok,lex); } else { // std::cout << "EPrime => null\n"; return true; } if (!Term()) return false; if (plus) { assembly.push_back(icode(a_line, "ADD")); ++a_line; } else { assembly.push_back(icode(a_line, "SUB")); ++a_line; } if (!EPrime()) return false; // if (plus) { // std::cout << "EPrime => + Term EPrime\n"; // } else { // std::cout << "EPrime => - Term EPrime\n"; // } return true; }
bool Parser::TPrime() { bool div = false; if ("*" == lex) { L.getTokLex(tok,lex); } else if ("/" == lex) { div = true; L.getTokLex(tok,lex); } else { // std::cout << "TPrime => null\n"; return true; } if (!Factor()) return false; if (!TPrime()) return false; if (div) { assembly.push_back(icode(a_line, "DIV")); ++a_line; } else { assembly.push_back(icode(a_line, "MUL")); ++a_line; } // if (div) { // std::cout << "TPrime => / Factor TPrime\n"; // } else { // std::cout << "TPrime => * Factor TPrime\n"; // } return true; }
bool Parser::Factor() { if ("identifier" == tok) { //identifier or function call // ident(); int a; if (!get_symbol_addr(lex, a)) { //++++++++++++++++++++++++++++++++++++++ // check funcs. if found call FuncCall(), else not declared std::cout << "Error: Variable '" << lex << "' not declared.\n"; return false; } assembly.push_back(icode(a_line,"PUSHM",std::to_string(a))); ++a_line; L.getTokLex(tok,lex); // std::cout << "Factor => ident\n"; return true; } else if ("integer" == tok) { //integer assembly.push_back(icode(a_line,"PUSHV",lex)); ++a_line; // std::cout << "int = " << lex << std::endl; L.getTokLex(tok,lex); // std::cout << "Factor => int\n"; return true; } else if ("real number" == tok) { // real assembly.push_back(icode(a_line,"PUSHV",lex)); ++a_line; // std::cout << "real = " << lex << std::endl; L.getTokLex(tok,lex); // std::cout << "Factor => real\n"; return true; } else if ("true" == lex) { //true assembly.push_back(icode(a_line,"PUSHV","1")); ++a_line; L.getTokLex(tok,lex); // std::cout << "Factor => bool\n"; return true; } else if ("false" == lex) { //false assembly.push_back(icode(a_line,"PUSHV","0")); ++a_line; L.getTokLex(tok,lex); // std::cout << "Factor => bool\n"; return true; } else if ("(" == lex) { // ( Expr ) L.getTokLex(tok,lex); if (!Expr()) return false; if (!(")" == lex)) { std::cout << "Expression not closed by ')'\n"; return false; } else { L.getTokLex(tok,lex); // std::cout << "Factor => ( Expr )\n"; return true; } } else { std::cout << "Error parsing factor\n"; return false; } }
bool Parser::OptElseIf(int* jzp, std::vector< int > *jp) { if (!("elseif" == lex)) { // std::cout << "OptElseIf => null\n"; return true; } else { L.getTokLex(tok,lex); } assembly.push_back(icode(a_line,"JUMP")); (*jp).push_back(a_line-1); ++a_line; assembly[(*jzp)].addr = std::to_string(a_line); if (!("(" == lex)) { std::cout << "elseif keyword not followed by '('\n"; return false; } else { L.getTokLex(tok,lex); } if (!Condition()) return false; if (!(")" == lex)) { std::cout << "elseif condition not followed by ')'\n"; return false; } else { L.getTokLex(tok,lex); } if (!("begin" == lex)) { std::cout << "elseif body does not begin with keyword 'begin'\n"; return false; } else { L.getTokLex(tok,lex); } assembly.push_back(icode(a_line, "JMPZ")); *jzp = a_line-1; ++a_line; if (!OptStmtList()) return false; if (!("end" == lex)) { std::cout << "elseif body does not end with keyword 'end'\n"; return false; } else { L.getTokLex(tok,lex); } if (!OptElseIf(jzp, jp)) return false; // std::cout << "OptElseIf => elseif ( Condition ) begin OptStmtList end OptElseIf\n"; return true; }
bool Parser::While() { if (!("while" == lex)) { std::cout << "Expected 'while'\n"; return false; } else { L.getTokLex(tok,lex); } if (!("(" == lex)) { std::cout << "while keyword not followed by '('\n"; return false; } else { L.getTokLex(tok,lex); } int cond_line = a_line; if (!Condition()) return false; if (!(")" == lex)) { std::cout << "while condition not followed by ')'\n"; return false; } else { L.getTokLex(tok,lex); } if (!("begin" == lex)) { std::cout << "while body does not begin with keyword 'begin'\n"; return false; } else { L.getTokLex(tok,lex); } assembly.push_back(icode(a_line, "JMPZ")); int jz_instr = a_line-1; ++a_line; if (!OptStmtList()) return false; assembly.push_back(icode(a_line,"JUMP",std::to_string(cond_line))); ++a_line; assembly[jz_instr].addr = std::to_string(a_line); if (!("end" == lex)) { std::cout << "while body does not end with keyword 'end'\n"; return false; } else { L.getTokLex(tok,lex); } // std::cout << "While => while ( Condition ) begin OptStmtList end\n"; return true; }
bool Parser::If() { // watch out for pointer magic in these 'if' 'elseif' 'else' functions if (!("if" == lex)) { std::cout << "Expected 'if'\n"; return false; } else { L.getTokLex(tok,lex); } if (!("(" == lex)) { std::cout << "if keyword not followed by '('\n"; return false; } else { L.getTokLex(tok,lex); } if (!Condition()) return false; if (!(")" == lex)) { std::cout << "if condition not followed by ')'\n"; return false; } else { L.getTokLex(tok,lex); } if (!("begin" == lex)) { std::cout << "if body does not begin with keyword 'begin'\n"; return false; } else { L.getTokLex(tok,lex); } assembly.push_back(icode(a_line, "JMPZ")); int jz = a_line-1; ++a_line; int *jzp = &(jz); if (!OptStmtList()) return false; if (!("end" == lex)) { std::cout << "if body does not end with keyword 'end'\n"; return false; } else { L.getTokLex(tok,lex); } std::vector< int > jumps; std::vector< int > *jp = &jumps; if (!OptElseIf(jzp, jp)) return false; if (!OptElse(jz)) return false; for (int i=0; i < jumps.size(); i++) { assembly[jumps[i]].addr = std::to_string(a_line); } // std::cout << "If => if ( Condition ) begin OptStmtList end OptElseIf OptElse\n"; return true; }
void Parser::end_nop() { for (int i = 0; i < assembly.size(); i++) { if (assembly[i].instr == "JUMP" || assembly[i].instr == "JMPZ") { if (std::to_string(a_line) == assembly[i].addr) { assembly.push_back(icode(a_line, "NOP")); return; } } } }
bool Parser::OptReads() { if (")" == lex) { // std::cout << "OptVars => null\n"; return true; } if (!("," == lex)) { std::cout << "Variable list not delimited by ','\n"; return false; } else { L.getTokLex(tok,lex); } if (!("identifier" == tok)) { std::cout << "Invalid identifier in variable list\n"; return false; } else { // ident(); int a; if (!get_symbol_addr(lex, a)) { std::cout << "Error: Variable '" << lex << "' not declared.\n"; return false; } assembly.push_back(icode(a_line,"PUSHI")); ++a_line; assembly.push_back(icode(a_line,"POPM",std::to_string(a))); ++a_line; L.getTokLex(tok,lex); } if (!OptReads()) return false; // std::cout << "OptVars => , ident OptVars\n"; return true; }
bool Parser::Condition() { if (!Expr()) return false; if (!RelOp()) return false; if (!Expr()) return false; if (curr_relop == "<") { assembly.push_back(icode(a_line, "LESS")); ++a_line; } else if (curr_relop == ">") { assembly.push_back(icode(a_line, "GRTR")); ++a_line; } else if (curr_relop == "=") { assembly.push_back(icode(a_line, "EQL")); ++a_line; } else if (curr_relop == "<=") { assembly.push_back(icode(a_line, "GRTR")); ++a_line; assembly.push_back(icode(a_line, "NOT")); ++a_line; } else if (curr_relop == ">=") { assembly.push_back(icode(a_line, "LESS")); ++a_line; assembly.push_back(icode(a_line, "NOT")); ++a_line; } else if (curr_relop == "<>") { assembly.push_back(icode(a_line, "EQL")); ++a_line; assembly.push_back(icode(a_line, "NOT")); ++a_line; } else { std::cout << "Invalid relation encountered: " << curr_relop << std::endl; return false; } // std::cout << "Condition => Expr RelOp Expr\n"; return true; }
/***************************************************************************************************************************** open Prepares the database for use. An existing database is opened or otherwise an empty database is created. If the database is openend a table _META with meta info is loaded into a dictionary _META. The dictionary key is the code of the data element. A data element is either a tabel (dimension/event) or a field (characteristic/property). The value of the dictionary is the MET_INFO structure. This structure contains meta data about the data element. If the database is created an empty table _META is created. The function calls virtual functions, db_, which must be overriden by a derived class for a specific database implementation. ******************************************************************************************************************************/ void ARAS::open(DBInfo dbInfo) { if (isopen) return; // store db information this->dbInfo = dbInfo; // open or create database // performs the database specific initialization code, the specific information to be used is stored in the struct DBInfo. db_init_database(); // performs the database specific code to check whether a database alreay exists and open it. if (db_open_database()) { // read _META table from database into dictionary _META TABLE values; db_select_table("_META", {"CODE","INFO"}, values); for (auto i : values) _META.insert(std::pair<std::string, META_INFO>(i[0], META_INFO(i[1]))); } else { // performs the database specific code to create a new database based on DBInfo. db_create_database(); // create table _META: define the columns META_INFO imeta(data_type::DIM, 0, "_META", "", "", "_META", "CODE", 0, 0, 0, 0); META_INFO icode(data_type::STR, SIZE_META_CODE_MAX, "_META", "", "","_META", "", 0, 0, 1, 0); META_INFO idescs(data_type::STR, SIZE_DESCS_MAX, "_META", "", "", "_META", "", 0, 0, 0, 0); META_INFO idescl(data_type::STR, SIZE_DESCL_MAX, "_META", "", "", "_META", "", 0, 0, 0, 0); META_INFO iinfo(data_type::STR, 0, "_META", "", "", "_META", "",0, 0, 0, 0); // define the table META_TABLE meta = { { "_META", "Meta data", "Meta data", imeta }, { "CODE", "CODE", "CODE", icode }, { "DESCS", "Short Description", "Short Description", idescs }, { "DESCL", "Long Description", "Long Description", idescl }, { "INFO", "INFO", "INFO", iinfo } }; // performs the database specific code to create a new table db_create_table(meta); // load the meta data into the dictionary and the database table _META for (auto i : meta) insert_meta(i); } }
bool Parser::Write() { if (!("write" == lex)) { std::cout << "Expected write\n"; return false; } else { L.getTokLex(tok,lex); } if (!("(" == lex)) { std::cout << "'write' keyword not followed by '('\n"; return false; } else { L.getTokLex(tok,lex); } if (!Expr()) return false; assembly.push_back(icode(a_line, "POPO")); ++a_line; if (!(")" == lex)) { std::cout << "Expression in Write not followed by ')'\n"; return false; } else { L.getTokLex(tok,lex); } if (!(";" == lex)) { std::cout << "Write statement not ended with ';'\n"; return false; } else { L.getTokLex(tok,lex); } // std::cout << "Write => write ( Expr ) ;\n"; return true; }
bool Parser::Assign() { int rhs; if (!("identifier" == tok)) { std::cout << "Expected identifier\n"; return false; } else { // ident(); if (!get_symbol_addr(lex, rhs)) { std::cout << "Error: Variable '" << lex << "' not declared.\n"; return false; } L.getTokLex(tok,lex); } if (!("<-" == lex)) { std::cout << "Expected assignment, missing '<-'\n" << lex; return false; } else { L.getTokLex(tok,lex); } if (!Expr()) return false; assembly.push_back(icode(a_line,"POPM",std::to_string(rhs))); ++a_line; if (!(";" == lex)) { std::cout << "Assignment not terminated by';'\n"; return false; } else { L.getTokLex(tok,lex); } // std::cout << "Assign => ident <- Expr ;\n"; return true; }
bool Parser::OptElse(int jz) { if (!("else" == lex)) { // std::cout << "OptElse => null\n"; assembly[jz].addr = std::to_string(a_line); return true; } else { L.getTokLex(tok,lex); } if (!("begin" == lex)) { std::cout << "else body does not begin with keyword 'begin'\n"; return false; } else { L.getTokLex(tok,lex); } assembly.push_back(icode(a_line, "JUMP")); int jump_line = a_line-1; ++a_line; assembly[jz].addr = std::to_string(a_line); if (!OptStmtList()) return false; if (!("end" == lex)) { std::cout << "else body does not end with keyword 'end'\n"; return false; } else { L.getTokLex(tok,lex); } assembly[jump_line].addr = std::to_string(a_line); // std::cout << "OptElse => else begin OptStmtList end\n"; return true; }