int tokenTester() { char *expression = malloc(256 * sizeof(char)); Value **tokens; while (fgets(expression, 255, stdin)) { tokens = tokenize(expression); if (tokens) { printTokens(*tokens); } } free(expression); return 0; }
int main(int argc, char * argv[]) { if (argc != 2) { //print error statement printf("please enter exactly one string for tokenizing."); } else{ char *inputstring = argv[1]; TokenizerT *tk = TKCreate(inputstring); printTokens(tk); TKDestroy(tk); } return 0; }
int main(int argv, char** argc) { if (argv == 1) { std::cerr << "Must provide a command and arguments! Try parse, rewrite, compile, assemble\n"; return 0; } std::string flag = ""; std::string command = argc[1]; std::string input; std::string secondInput; if (std::string(argc[1]) == "-s") { flag = command.substr(1); command = argc[2]; input = ""; std::string line; while (std::getline(std::cin, line)) { input += line + "\n"; } secondInput = argv == 3 ? "" : argc[3]; } else { if (argv == 2) { std::cerr << "Not enough arguments for serpent cmdline\n"; throw(0); } input = argc[2]; secondInput = argv == 3 ? "" : argc[3]; } bool haveSec = secondInput.length() > 0; if (command == "parse" || command == "parse_serpent") { std::cout << printAST(parseSerpent(input), haveSec) << "\n"; } else if (command == "rewrite") { std::cout << printAST(rewrite(parseLLL(input, true)), haveSec) << "\n"; } else if (command == "compile_to_lll") { std::cout << printAST(compileToLLL(input), haveSec) << "\n"; } else if (command == "build_fragtree") { std::cout << printAST(buildFragmentTree(parseLLL(input, true))) << "\n"; } else if (command == "compile_lll") { std::cout << binToHex(compileLLL(parseLLL(input, true))) << "\n"; } else if (command == "dereference") { std::cout << printAST(dereference(parseLLL(input, true)), haveSec) <<"\n"; } else if (command == "pretty_assemble") { std::cout << printTokens(prettyAssemble(parseLLL(input, true))) <<"\n"; } else if (command == "pretty_compile_lll") { std::cout << printTokens(prettyCompileLLL(parseLLL(input, true))) << "\n"; } else if (command == "pretty_compile") { std::cout << printTokens(prettyCompile(input)) << "\n"; } else if (command == "assemble") { std::cout << assemble(parseLLL(input, true)) << "\n"; } else if (command == "serialize") { std::cout << binToHex(serialize(tokenize(input, Metadata(), false))) << "\n"; } else if (command == "flatten") { std::cout << printTokens(flatten(parseLLL(input, true))) << "\n"; } else if (command == "deserialize") { std::cout << printTokens(deserialize(hexToBin(input))) << "\n"; } else if (command == "compile") { std::cout << binToHex(compile(input)) << "\n"; } else if (command == "encode_datalist") { std::vector<Node> tokens = tokenize(input); std::vector<std::string> o; for (int i = 0; i < (int)tokens.size(); i++) { o.push_back(tokens[i].val); } std::cout << binToHex(encodeDatalist(o)) << "\n"; } else if (command == "decode_datalist") { std::vector<std::string> o = decodeDatalist(hexToBin(input)); std::vector<Node> tokens; for (int i = 0; i < (int)o.size(); i++) tokens.push_back(token(o[i])); std::cout << printTokens(tokens) << "\n"; } else if (command == "tokenize") { std::cout << printTokens(tokenize(input)); } else if (command == "biject") { if (argv == 3) std::cerr << "Not enough arguments for biject\n"; int pos = decimalToUnsigned(secondInput); std::vector<Node> n = prettyCompile(input); if (pos >= (int)n.size()) std::cerr << "Code position too high\n"; Metadata m = n[pos].metadata; std::cout << "Opcode: " << n[pos].val << ", file: " << m.file << ", line: " << m.ln << ", char: " << m.ch << "\n"; } }
int main(int argc, char* argv[]) { //read in file char str[100]; FILE *fp; fp=fopen(argv[1],"r"); if(fp==NULL) { fprintf(stderr,"Can't open input file!"); exit(1); } //LEXICAL ANALYSIS int numLines = 0; while(fgets(str,MAX_LINE_LEN,fp)!=NULL) { char* curPos = str; while(*curPos != '\n') { //CASE 1: NUM if(isdigit(*curPos)) { tokens[numTokens].type = 0; tokens[numTokens].lineNum = numLines; tokens[numTokens].lexeme = (char*)malloc(100); extractNum(curPos, tokens[numTokens].lexeme); numTokens++; continue; } //CASE 2: KEYWORD / IDENTIFIER / operator AND-OR if(isalpha(*curPos)) { //get alphanum token char* token = (char*)malloc(100); memset(token,'\0',100); getToken(curPos,token); //keyword case if(searchKeyword(token) != -1) tokens[numTokens].type = 1; else if(searchOperators(token) != -1) tokens[numTokens].type = 3; //identifier case else tokens[numTokens].type = 2; //add line num tokens[numTokens].lineNum = numLines; //add lexeme tokens[numTokens].lexeme = (char*)malloc(100); memcpy(tokens[numTokens].lexeme,token,strlen(token)); numTokens++; continue; } //CASE : WHITESPACE if(*curPos == ' ' || *curPos == '\t') curPos++; } // char* combined = (char*)malloc(100); // memcpy(combined,punctuation,strlen(punctuation)); // strcat(combined,symbols); // char* test = strtok(str,combined); // while(test != NULL) // { // std::cout<<test<<std::endl; // test = strtok(NULL,combined); // } // continue; // std::cout<<"here\n\n\n"<<std::endl; //Examine line char by char /* char* curPos = str; char* token = (char*)malloc(100);//NULL; memset(token,'\0',100); getToken(curPos,token); while(token != NULL) { //CASE 1: NUM CASE if(isdigit(*token)) { tokens[numTokens].type = 1; tokens[numTokens].lineNum = numLines; tokens[numTokens].lexeme = (char*)malloc(100); extractNum(token, tokens[numTokens].lexeme); numTokens++; } //CASE 2: KEYWORD CASE getToken(curPos,token); } */ /* // int str_i = 0; while(str_i < strlen(str)) { char c = str[str_i]; //CASE 1: NUMBER if(isdigit(c)) { //populate next element of tokens array tokens[numTokens].type = 1; tokens[numTokens].lineNum = numLines; //iterate through str until non-digit char encountered. //also iterate through lexeme to populate int lex_i = 0; while(isdigit(c) && str_i < strlen(str)) { tokens[numTokens].lexeme[lex_i] = c; lex_i++; str_i++; c = str[str_i]; } } //CASE 2: CHAR - always encapsulated by ' ' if(c == '\'') { str_i++; c = str[str_i]; } //CASE 3: } */ numLines++; } fclose(fp); printTokens(); fflush(stdout); //END FILE READ }
int main(int argc, const char* argv[]) { try { TCLAP::CmdLine cmd("Xylene", ' ', "pre-release"); TCLAP::SwitchArg asXML("", "xml", "Read file using the XML parser", cmd); TCLAP::SwitchArg printTokens("", "tokens", "Print token list", cmd); TCLAP::SwitchArg printAST("", "ast", "Print AST (if applicable)", cmd); TCLAP::SwitchArg printIR("", "ir", "Print LLVM IR (if applicable)", cmd); TCLAP::SwitchArg doNotParse("", "no-parse", "Don't parse the token list", cmd); TCLAP::SwitchArg doNotRun("", "no-run", "Don't execute the AST", cmd); std::vector<std::string> runnerValues {"llvm-lli", "llvm-llc"}; TCLAP::ValuesConstraint<std::string> runnerConstraint(runnerValues); TCLAP::ValueArg<std::string> runner("r", "runner", "How to run this code", false, "llvm-lli", &runnerConstraint, cmd, nullptr); TCLAP::ValueArg<std::string> code("e", "eval", "Code to evaluate", false, std::string(), "string", cmd, nullptr); TCLAP::ValueArg<std::string> filePath("f", "file", "Load code from this file", false, std::string(), "path", cmd, nullptr); cmd.parse(argc, argv); if (code.getValue().empty() && filePath.getValue().empty()) { TCLAP::ArgException arg("Must specify either option -e or -f"); cmd.getOutput()->failure(cmd, arg); } std::unique_ptr<AST> ast; if (asXML.getValue()) { if (doNotParse.getValue()) return NORMAL_EXIT; if (filePath.getValue().empty()) { TCLAP::ArgException arg("XML option only works with files"); cmd.getOutput()->failure(cmd, arg); } ast = std::make_unique<AST>(XMLParser().parse(rapidxml::file<>(filePath.getValue().c_str())).getTree()); } else { std::string input; if (!filePath.getValue().empty()) { std::ifstream file(filePath.getValue()); std::stringstream buffer; buffer << file.rdbuf(); input = buffer.str(); } else { input = code.getValue(); } auto lx = Lexer(); lx.tokenize(input, filePath.getValue().empty() ? "<cli-eval>" : filePath.getValue()); if (printTokens.getValue()) for (auto tok : lx.getTokens()) println(tok); if (doNotParse.getValue()) return NORMAL_EXIT; ast = std::make_unique<AST>(TokenParser().parse(lx.getTokens()).getTree()); } if (printAST.getValue()) ast->print(); if (doNotRun.getValue()) return NORMAL_EXIT; CompileVisitor::Link v = CompileVisitor::create("Command Line Module", *ast); v->visit(); if (printIR.getValue()) v->getModule()->dump(); if (runner.getValue() == "llvm-lli") { return Runner(v).run(); } else if (runner.getValue() == "llvm-llc") { println("Not yet implemented!"); // TODO } } catch (const TCLAP::ExitException& arg) { return CLI_ERROR; } catch (const TCLAP::ArgException& arg) { println("TCLAP error", arg.error(), "for", arg.argId()); return TCLAP_ERROR; } catch (const Error& err) { println(err.what()); return USER_PROGRAM_ERROR; } // If we're debugging, crash the program on InternalError #ifndef CRASH_ON_INTERNAL_ERROR catch (const InternalError& err) { println(err.what()); return INTERNAL_ERROR; } #endif return 0; }
db_lookup_retval_t SqlParser::parseSql(std::set<std::string> &dbs, int *txLevel, bool parseMaster) { dbs.clear(); StringVector tables, aliases; if (getTokensLen() <= 0) { log_warning("empty sql for dababase lookup!\n"); return RET_ERROR_UNPARSABLE; } switch (getTokenId(0)) { case TK_SQL_SELECT: { int usemaster = 0; if (parseMaster) usemaster = 1; // special handling for our get unique id function call. if (getTokensLen() > 1 && getTokenStr(1) == "get_next_id") return RET_USE_DEFAULT_DATABASE; int fromStart, fromEnd; if (!getSqlFrom(0, &fromStart, &fromEnd)) { if ((getTokensLen() > 3 && getTokenId(1) == TK_LITERAL && getTokenId(2) == TK_OBRACE) || (getTokensLen() == 2 && getTokenId(1) == TK_LITERAL)) { // for special stored procedures return RET_USE_ALL_PARTITIONS; } printTokens("no FROM found, using default db: "); return RET_USE_DEFAULT_DATABASE; } if (!parseTableNameAndAlias(fromStart, fromEnd, tables, aliases)) { printTokens("could not parse table alias, using default db: "); return RET_USE_DEFAULT_DATABASE; } // for non-partitioned tables, we can use any db // since each db should have a view of it bool partitioned = false; for (size_t i = 0; i < tables.size(); i++) { if (dbPart->isPartitionedTable(tables[i])) { partitioned = true; break; } } if (!setDefaultLimit()) { printTokens("error in modifying LIMIT: "); return RET_ERROR_UNPARSABLE; } /* if (!partitioned) return ((*txLevel) > 0 ? RET_USE_DEFAULT_DATABASE : RET_USE_ANY_PARTITION); */ int whereStart, whereEnd; if (!getSqlWhere(fromEnd, &whereStart, &whereEnd)) { // add LIMIT, change the offset to 0 if needed uint64_t aa = 0; dbPart->getPartitionNum(tables[0], &aa); for (size_t i = 0; i < aa; i++) { std::string db; getDbMapping(tables[0], "", i, db, usemaster, 0); if (!db.empty()) dbs.insert(db); } return RET_USE_ALL_PARTITIONS; } for (size_t i = 0; i < tables.size(); i++) { std::string partitionKey; getPartitionKey(tables[i], partitionKey); if (partitionKey.empty()) { std::string db; getDbMapping(tables[i], "", 0, db, usemaster, 0); if (!db.empty()) dbs.insert(db); continue; } std::vector<uint64_t> keyValues; if (!findPartitionKeyValue(whereStart, whereEnd, tables[i], aliases[i], partitionKey, keyValues)) { printTokens("unrecognized key ranges: "); return RET_ERROR_UNPARSABLE; } if (keyValues.size() == 0) { uint64_t aa = 0; dbPart->getPartitionNum(tables[0], &aa); for (size_t i = 0; i < aa; i++) { std::string db; getDbMapping(tables[0], "", i, db, usemaster, 0); if (!db.empty()) dbs.insert(db); } return RET_USE_ALL_PARTITIONS; } // find the db partition for all the IDs for (size_t k = 0; k < keyValues.size(); k++) { std::string db; getDbMapping(tables[i], partitionKey, keyValues[k], db, usemaster, 0); if (!db.empty()) dbs.insert(db); } } if (dbs.empty()) return RET_USE_ALL_PARTITIONS; return RET_DB_LOOKUP_SUCCESS; } case TK_SQL_UPDATE: { int setPos; if (!findToken(0, getTokensLen(), TK_SQL_SET, &setPos)) { printTokens("could not find SET in UPDATE: "); return RET_ERROR_UNPARSABLE; }; if (getTokenId(setPos - 1) != TK_LITERAL) { printTokens("expecting table name before SET: "); return RET_ERROR_UNPARSABLE; } std::string table = getTokenStr(setPos - 1); // for nonpartitioned tables, update the default master db if (!(dbPart->isPartitionedTable(table))) { std::string db; getDbMapping(table, "", 0, db, 1, 0); if (!db.empty()) dbs.insert(db); return RET_USE_ALL_PARTITIONS; } int whereStart, whereEnd; if (!getSqlWhere(setPos + 1, &whereStart, &whereEnd)) { printTokens("no WHERE found: "); return RET_ERROR_UNPARSABLE; } std::string partitionKey; getPartitionKey(table, partitionKey); g_assert(!partitionKey.empty()); std::vector<uint64_t> keyValues; if (!findPartitionKeyValue(whereStart, whereEnd, table, "", partitionKey, keyValues)) { printTokens("unrecognized ranges: "); return RET_ERROR_UNPARSABLE; } // find the db partition for all the IDs for (size_t k = 0; k < keyValues.size(); k++) { std::string db; getDbMapping(table, partitionKey, keyValues[k], db, 1, 0); if (!db.empty()) dbs.insert(db); } if (dbs.empty()) return RET_USE_ALL_PARTITIONS; return RET_DB_LOOKUP_SUCCESS; } case TK_SQL_INSERT: { // support format: INSERT ... <table> (...) VALUES (....) int pos; uint64_t insertid = 0; if (!findToken(1, getTokensLen(), TK_LITERAL, &pos)) { printTokens("could not find table name: "); return RET_ERROR_UNPARSABLE; } std::string table = getTokenStr(pos); std::string partitionKey; getPartitionKey(table, partitionKey); if (getTokenId(++pos) != TK_OBRACE) { printTokens("unrecognized INSERT: "); return RET_ERROR_UNPARSABLE; } pos++; std::string autoIncrementColumn; dbPart->getAutoIncrementColumn(table, autoIncrementColumn); int keyPos = -1; int autoColPos = -1; for (int i = pos; i < getTokensLen(); i++) { if ((getTokenId(i) == TK_CBRACE) || (autoColPos >= 0 && keyPos >= 0)) break; if (getTokenId(i) == TK_LITERAL && tokComp(i, partitionKey) == 0) { keyPos = i - pos; continue; } if (getTokenId(i) == TK_LITERAL && tokComp(i, autoIncrementColumn) == 0) { autoColPos = i - pos; } } if ((!partitionKey.empty()) && keyPos == -1 && partitionKey != autoIncrementColumn) { log_warning("could not find the partition key %s:", partitionKey.c_str()); printTokens(); return RET_ERROR_UNPARSABLE; } if ((!partitionKey.empty()) && keyPos == -1) { // special handling for the case in which partition key type is auto increment. // need to get the id first and then modify the INSERT uint64_t id; if (!dbPart->getNextUniqueId(table, &id)) { log_warning("could not get next unique id for %s", partitionKey.c_str()); printTokens(); return RET_DB_LOOKUP_ERROR; } insertid = id; std::string db; getDbMapping(table, partitionKey, id, db, 1, id); if (!db.empty()) dbs.insert(db); else { printTokens("could not find db for id %d: "); return RET_DB_LOOKUP_ERROR; } if (modifySqlForInsert(partitionKey, id)) { if (partitionKey == autoIncrementColumn || autoIncrementColumn.empty()) return RET_DB_LOOKUP_SUCCESS; } else { log_warning("could not insert id for %s ", partitionKey.c_str()); printTokens(); return RET_DB_LOOKUP_ERROR; } } if (!autoIncrementColumn.empty() && autoColPos < 0 && (partitionKey != autoIncrementColumn)) { // need to get unique ids for auto increment columns uint64_t id; if (!dbPart->getNextUniqueId(table, &id)) { log_warning("could not get next unique id for %s", autoIncrementColumn.c_str()); printTokens(); return RET_DB_LOOKUP_ERROR; } insertid = id; if (modifySqlForInsert(autoIncrementColumn, id)) { // for nonparitioned table INSERT, use the default master db if (partitionKey.empty()) return RET_USE_DEFAULT_DATABASE; if (keyPos == -1) return RET_DB_LOOKUP_SUCCESS; } else { log_warning("could not insert id for %s ", autoIncrementColumn.c_str()); printTokens(); return RET_DB_LOOKUP_ERROR; } } // for nonparitioned table INSERT, use the default master db if (partitionKey.empty()) { std::string db; getDbMapping(table, "", 0, db, 1, insertid); if (!db.empty()) dbs.insert(db); return RET_USE_ALL_PARTITIONS; } pos += keyPos; int valPos; if (!findToken(pos, getTokensLen(), TK_SQL_VALUES, &valPos)) { printTokens("VALUES is not found: "); return RET_ERROR_UNPARSABLE; } if (getTokenId(valPos + 1) != TK_OBRACE) { printTokens("expecting '(' after VALUES: "); return RET_ERROR_UNPARSABLE; } pos = valPos + 2 + keyPos; if (pos < getTokensLen()) {//dqm //if (pos < getTokensLen() && getTokenId(pos) == TK_INTEGER) { uint64_t id = tokenToUint64(pos); std::string db; getDbMapping(table, partitionKey, id, db, 1, insertid); if (!db.empty()) dbs.insert(db); if (dbs.empty()) { printTokens("could not find db mapping: "); return RET_ERROR_UNPARSABLE; } return RET_DB_LOOKUP_SUCCESS; } else { log_warning("could not recognize value for %s:", partitionKey.c_str()); printTokens(); return RET_ERROR_UNPARSABLE; } break; } case TK_SQL_REPLACE: { // support format: replace ... <table> (...) VALUES (....) int pos; uint64_t insertid = 0; if (!findToken(1, getTokensLen(), TK_LITERAL, &pos)) { printTokens("could not find table name: "); return RET_ERROR_UNPARSABLE; } std::string table = getTokenStr(pos); std::string partitionKey; getPartitionKey(table, partitionKey); if (getTokenId(++pos) != TK_OBRACE) { printTokens("unrecognized INSERT: "); return RET_ERROR_UNPARSABLE; } pos++; std::string autoIncrementColumn; dbPart->getAutoIncrementColumn(table, autoIncrementColumn); int keyPos = -1; int autoColPos = -1; for (int i = pos; i < getTokensLen(); i++) { if ((getTokenId(i) == TK_CBRACE) || (autoColPos >= 0 && keyPos >= 0)) break; if (getTokenId(i) == TK_LITERAL && tokComp(i, partitionKey) == 0) { keyPos = i - pos; continue; } if (getTokenId(i) == TK_LITERAL && tokComp(i, autoIncrementColumn) == 0) { autoColPos = i - pos; } } if ((!partitionKey.empty()) && keyPos == -1 && partitionKey != autoIncrementColumn) { log_warning("could not find the partition key %s:", partitionKey.c_str()); printTokens(); return RET_ERROR_UNPARSABLE; } if ((!partitionKey.empty()) && keyPos == -1) { // special handling for the case in which partition key type is auto increment. // need to get the id first and then modify the INSERT uint64_t id; if (!dbPart->getNextUniqueId(table, &id)) { log_warning("could not get next unique id for %s", partitionKey.c_str()); printTokens(); return RET_DB_LOOKUP_ERROR; } insertid = id; std::string db; getDbMapping(table, partitionKey, id, db, 1, id); if (!db.empty()) dbs.insert(db); else { printTokens("could not find db for id %d: "); return RET_DB_LOOKUP_ERROR; } if (modifySqlForInsert(partitionKey, id)) { if (partitionKey == autoIncrementColumn || autoIncrementColumn.empty()) return RET_DB_LOOKUP_SUCCESS; } else { log_warning("could not insert id for %s ", partitionKey.c_str()); printTokens(); return RET_DB_LOOKUP_ERROR; } } if (!autoIncrementColumn.empty() && autoColPos < 0 && (partitionKey != autoIncrementColumn)) { // need to get unique ids for auto increment columns uint64_t id; if (!dbPart->getNextUniqueId(table, &id)) { log_warning("could not get next unique id for %s", autoIncrementColumn.c_str()); printTokens(); return RET_DB_LOOKUP_ERROR; } insertid = id; if (modifySqlForInsert(autoIncrementColumn, id)) { // for nonparitioned table INSERT, use the default master db if (partitionKey.empty()) return RET_USE_DEFAULT_DATABASE; if (keyPos == -1) return RET_DB_LOOKUP_SUCCESS; } else { log_warning("could not insert id for %s ", autoIncrementColumn.c_str()); printTokens(); return RET_DB_LOOKUP_ERROR; } } // for nonparitioned table INSERT, use the default master db if (partitionKey.empty()) { std::string db; getDbMapping(table, "", 0, db, 1, insertid); if (!db.empty()) dbs.insert(db); return RET_USE_ALL_PARTITIONS; } pos += keyPos; int valPos; if (!findToken(pos, getTokensLen(), TK_SQL_VALUES, &valPos)) { printTokens("VALUES is not found: "); return RET_ERROR_UNPARSABLE; } if (getTokenId(valPos + 1) != TK_OBRACE) { printTokens("expecting '(' after VALUES: "); return RET_ERROR_UNPARSABLE; } pos = valPos + 2 + keyPos; if (pos < getTokensLen()) {//dqm //if (pos < getTokensLen() && getTokenId(pos) == TK_INTEGER) { uint64_t id = tokenToUint64(pos); std::string db; getDbMapping(table, partitionKey, id, db, 1, insertid); if (!db.empty()) dbs.insert(db); if (dbs.empty()) { printTokens("could not find db mapping: "); return RET_ERROR_UNPARSABLE; } return RET_DB_LOOKUP_SUCCESS; } else { log_warning("could not recognize value for %s:", partitionKey.c_str()); printTokens(); return RET_ERROR_UNPARSABLE; } break; } case TK_SQL_ALTER: { std::string tableName; if (getTokensLen() >= 3 && getTokenId(1) == TK_SQL_TABLE) { tableName = getTokenStr(2); } else if (getTokensLen() >= 4 && getTokenId(1) == TK_SQL_IGNORE && getTokenId(2) == TK_SQL_TABLE) { tableName = getTokenStr(3); } else break; if (dbPart->isPartitionedTable(tableName)) return RET_USE_ALL_PARTITIONS; else return RET_USE_DEFAULT_DATABASE; } case TK_SQL_CALL: { return RET_USE_ALL_PARTITIONS; } case TK_SQL_SHOW: { if (getTokensLen() == 4 && getTokenId(2) == TK_SQL_FROM && strcasecmp(getTokenStr(1).c_str(), "fields") == 0) { if (dbPart->isPartitionedTable(getTokenStr(3))) { return RET_USE_ANY_PARTITION; } return RET_USE_DEFAULT_DATABASE; } if (getTokensLen() == 2 && strcasecmp(getTokenStr(1).c_str(), "tables") == 0) { //special handling for show tables; // std::string sql = "select table_name "; sql.append(" from kind_setting order by table_name"); g_string_truncate(inputSql, NET_HEADER_SIZE + 1); g_string_append_len(inputSql, sql.data(), sql.size()); network_mysqld_proto_set_header_len((unsigned char *) (inputSql->str), inputSql->len - NET_HEADER_SIZE); return RET_USE_DEFAULT_DATABASE; } else return RET_USE_DEFAULT_DATABASE; break; } case TK_SQL_DELETE: { int fromPos; if (!findToken(1, getTokensLen(), TK_SQL_FROM, &fromPos)) { printTokens("could not find FROM in DELETE: "); return RET_ERROR_UNPARSABLE; }; if (fromPos >= getTokensLen() - 1) { printTokens("could not find table name in DELETE: "); return RET_ERROR_UNPARSABLE; } std::string table = getTokenStr(fromPos + 1); // for nonpartitioned tables, update the default master db if (!(dbPart->isPartitionedTable(table))) { std::string db; getDbMapping(table, "", 0, db, 1, 0); if (!db.empty()) dbs.insert(db); return RET_USE_ALL_PARTITIONS; } int whereStart, whereEnd; if (!getSqlWhere(fromPos + 1, &whereStart, &whereEnd)) { printTokens("no WHERE found: "); return RET_ERROR_UNPARSABLE; } std::string partitionKey; getPartitionKey(table, partitionKey); g_assert(!partitionKey.empty()); std::vector<uint64_t> keyValues; if (!findPartitionKeyValue(whereStart, whereEnd, table, "", partitionKey, keyValues)) { printTokens("unrecognized ranges: "); return RET_ERROR_UNPARSABLE; } // find the db partition for all the IDs for (size_t k = 0; k < keyValues.size(); k++) { std::string db; getDbMapping(table, partitionKey, keyValues[k], db, 1, 0); if (!db.empty()) dbs.insert(db); } if (dbs.empty()) return RET_USE_ALL_PARTITIONS; return RET_DB_LOOKUP_SUCCESS; } case TK_SQL_DESC: case TK_SQL_DESCRIBE: { if (getTokensLen() >= 2) { std::string tableName = getTokenStr(1); if (dbPart->isPartitionedTable(tableName)) return RET_USE_ANY_PARTITION; else return RET_USE_DEFAULT_DATABASE; } return RET_ERROR_UNPARSABLE; } case TK_SQL_SET: { if ((getTokensLen() >= 4) && (getTokenId(1) == TK_SQL_AUTOCOMMIT) && (getTokenStr(3).compare("0") == 0)) { (*txLevel)++; } return RET_USE_ALL_DATABASES; } case TK_SQL_START: case TK_SQL_BEGIN: { (*txLevel)++; return RET_USE_ALL_DATABASES; } case TK_SQL_COMMIT: case TK_SQL_ROLLBACK: { (*txLevel)--; return RET_USE_ALL_DATABASES; } default: { break; } } printTokens("unrecognized query, using default master db: "); return RET_USE_DEFAULT_DATABASE; }
int main(int argc, char *argv[]) { int i; int quiet = 0; displayMode dm = dmSI; int rc = 0; char *ifile = NULL; FILE *iptr; FILE *rcptr; int usestdin = 0; char siPrefix = '\0'; char *home = getenv("HOME"); int rcpathlen; int precision = -1; char *token; char line[200]; setlocale(LC_ALL, ""); bindtextdomain("ralcalc", LOCALEDIR); textdomain("ralcalc"); if(argc==2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help") || !strcmp(argv[1], "-v") || !strcmp(argv[1], "--version"))){ printUsage(); return 1; } if(argc==2 && (!strcmp(argv[1], "-a") || !strcmp(argv[1], "--all"))){ printTokens(); return 1; } if(home){ rcpathlen = strlen(home) + strlen("/.ralcalcrc") + 1; rcpath = (char *)malloc(rcpathlen * sizeof(char)); snprintf(rcpath, rcpathlen, "%s/.ralcalcrc", home); rcptr = fopen(rcpath, "rb"); if(rcptr){ if(fgets(line, 200, rcptr)){ while(line[strlen(line)-1] == '\n'){ line[strlen(line)-1] = '\0'; } token = strtok(line, " "); if(!strcmp(line, "-e")){ dm = dmExponent; }else if(!strcmp(line, "-r")){ dm = dmRaw; }else if(!strcmp(line, "-s")){ dm = dmSI; token = strtok(NULL, " "); siPrefix = token[0]; } } fclose(rcptr); } } for(i = 1; i < argc; i++){ if(!strcmp(argv[i], "-q")){ quiet = 1; argv[i][0] = '\0'; }else if(!strcmp(argv[i], "-e")){ dm = dmExponent; argv[i][0] = '\0'; }else if(!strcmp(argv[i], "-f")){ if(i < argc - 1){ ifile = strdup(argv[i+1]); argv[i][0] = '\0'; argv[i+1][0] = '\0'; i++; }else{ printUsage(); return 1; } }else if(!strcmp(argv[i], "-i")){ usestdin = 1; }else if(!strcmp(argv[i], "-p")){ if(i < argc - 1){ precision = atoi(argv[i+1]); argv[i][0] = '\0'; argv[i+1][0] = '\0'; i++; if(precision < 0){ fprintf(stderr, _("Error: Precision must be a positive integer.\n")); return 1; } }else{ printUsage(); return 1; } }else if(!strcmp(argv[i], "-r")){ dm = dmRaw; argv[i][0] = '\0'; }else if(!strcmp(argv[i], "-s")){ if(i < argc - 1){ if(strlen(argv[i+1]) != 1){ fprintf(stderr, _("Error: Invalid SI prefix '%s' for '-s' option.\n"), argv[i+1]); return 1; }else{ dm = dmSI; switch(argv[i+1][0]){ case 'Y': case 'Z': case 'E': case 'P': case 'T': case 'G': case 'M': case 'k': case 'm': case 'u': case 'n': case 'p': case 'f': case 'a': case 'z': case 'y': siPrefix = argv[i+1][0]; break; default: fprintf(stderr, _("Error: Invalid SI prefix '%s' for '-s' option.\n"), argv[i+1]); return 1; break; } argv[i][0] = '\0'; argv[i+1][0] = '\0'; i++; } }else{ printUsage(); return 1; } } } /* Figure out the path to .ralcalc_result for loading/saving. */ if(home){ rcpathlen = strlen(home) + strlen("/.ralcalc_result") + 1; rcpath = (char *)malloc(rcpathlen * sizeof(char)); snprintf(rcpath, rcpathlen, "%s/.ralcalc_result", home); } /* Do calculation based on input arguments first */ if(doLineCalculation(argc, argv, quiet, dm, siPrefix, precision)) rc = 1; /* Do calculations from a disk file */ if(ifile){ iptr = fopen(ifile, "rt"); if(!iptr){ fprintf(stderr, _("Error: Unable to open file \"%s\"\n"), ifile); return 1; } if(doFileInput(iptr, quiet, dm, siPrefix, precision)) rc = 1; fclose(iptr); } /* Read calculations from stdin */ if(usestdin){ if(doFileInput(stdin, quiet, dm, siPrefix, precision)) rc = 1; } if(rcpath){ free(rcpath); } return rc; }
int main(int argc, char* argv[]) { //read in file char str[MAX_LINE_LEN]; FILE *fp; fp=fopen(argv[1],"r"); if(fp==NULL) { fprintf(stderr,"Can't open input file!"); exit(1); } //LEXICAL ANALYSIS int numLines = 0; int type = -1; char* val = (char*)malloc(MAX_LINE_LEN); while(fgets(str,MAX_LINE_LEN,fp)!=NULL) { char* curPos = str; while(*curPos != '\n' && strcmp(curPos,"") != 0) { //CASE : WHITESPACE if(*curPos == ' ' || *curPos == '\t') { curPos++; continue; } //CASE 1: NUM else if(isdigit(*curPos)) { extractNum(curPos,val); type = 0; } //CASE 2: KEYWORD / IDENTIFIER / operator AND-OR else if(isalpha(*curPos)) { //get alphanum token getToken(curPos,val); if(searchArray(keywords,val,NUM_KEYWORDS) != -1) type = 1; else if(searchArray(boolSymbols,val,NUM_BOOLSYMBOLS) != -1) type = 12; else //identifier type = 2; } else if(searchArray(mathSymbols,*curPos,NUM_MATHSYMBOLS) != -1) { type = 6; val[0] = *curPos; curPos++; } else if(searchArray(relationalSymbols,*curPos,NUM_RELATIONALSYMBOLS) != -1) { type = 7; val[0] = *curPos; curPos++; } else if(searchArray(equalSymbols,*curPos,NUM_EQUALSYMBOLS) != -1) { type = 8; val[0] = *curPos; curPos++; } else if(searchArray(arraySymbols,*curPos,NUM_ARRAYSYMBOLS) != -1) { type = 9; val[0] = *curPos; curPos++; } else if(searchArray(blockSymbols,*curPos,NUM_BLOCKSYMBOLS) != -1) { type = 10; val[0] = *curPos; curPos++; } else if(searchArray(parenSymbols,*curPos,NUM_PARENSYMBOLS) != -1) { type = 11; val[0] = *curPos; curPos++; } else if(searchArray(boolSymbols,*curPos,NUM_BOOLSYMBOLS) != -1) { type = 12; val[0] = *curPos; curPos++; } //CASE 4: PUNCTUATION else if(searchArray(punctuation,*curPos,NUM_PUNCTUATION) != -1) { type = 4; val[0] = *curPos; curPos++; } //CASE 5: CHAR else if(*curPos == '\'') { curPos++; if(*curPos == '\\') curPos++; type = 5; val[0] = *curPos; curPos = curPos+2; } //CASE : UNKNOWN else { type = 13; val[0] = *curPos; curPos++; //addToken(13,numLines,val); } addToken(type,numLines,val); type = -1; memset(val,'\0',strlen(val)); } numLines++; } fclose(fp); printTokens(); fflush(stdout); //END FILE READ }
//******************************************************* // Parser::parse //******************************************************* void Parser::parse() { static const uint32_t ACTION_WIDTH = 17; static const uint32_t STACK_WIDTH = 1; // Make the second column the correct maximum size, always. std::ostringstream dummy1; Token dummy2; printTokens(dummy1, dummy2); static uint32_t TOKENS_WIDTH = dummy1.str().size(); if (myPrintParse) { std::cout << std::left << std::setw(ACTION_WIDTH) << "Parser Action" << " | " << std::setw(TOKENS_WIDTH) << "Remaining Tokens" << " | " << std::setw(STACK_WIDTH) << "Stack" << std::endl << std::right; } mySemanticStack.initialize(); myStack.push(myGrammar.getStartSymbol()); Token token{myScanner.scan()}; printState(token); while (myStack.size() > 0) { // variables for printing the parse std::ostringstream stackContents; std::ostringstream remainingTokens; std::ostringstream predictValue; if (myPrintParse) { printTokens(remainingTokens, token); printStack(stackContents, myStack); } auto expectedSymbol = myStack.top(); if (typeid(*expectedSymbol.get()) == typeid(NonTerminalSymbol)) { auto productionNumber = myPredictTable.getProductionNumber( expectedSymbol, token.getTerminal()); if (productionNumber > 0) { predictValue << "Predict(" << productionNumber << ")"; myStack.pop(); myStack.push(mySemanticStack.getEOPSymbol()); auto production = myGrammar.getProduction(productionNumber); auto rhs = production->getRHS(); auto rhsIter = rhs.rbegin(); uint32_t numberGrammarSymbols = 0; while (rhsIter != rhs.rend()) { std::shared_ptr<Symbol> rhsSymbol = *rhsIter; if (GrammarAnalyzer::isGrammarSymbol(rhsSymbol)) { ++numberGrammarSymbols; } if (!(*rhsSymbol == *Lambda::getInstance())) { myStack.push(rhsSymbol); } ++rhsIter; } mySemanticStack.expand(numberGrammarSymbols); } else { std::ostringstream error; error << "No production found for symbol " << *expectedSymbol << " and token " << *(token.getTerminal()) << "."; myEWTracker.reportError(token.getLine(), token.getColumn(), error.str()); // Error recovery myStack.pop(); // Move past the bad symbol. } } else if (typeid(*expectedSymbol.get()) == typeid(TerminalSymbol)) { if (*expectedSymbol == *(token.getTerminal())) { predictValue << "Match"; mySemanticStack.replaceAtCurrentIndex(SemanticRecord( PlaceholderRecord(token))); myStack.pop(); token = myScanner.scan(); } else { std::ostringstream error; error << "Expected " << *expectedSymbol << ", instead found " << *(token.getTerminal()) << "."; myEWTracker.reportError(token.getLine(), token.getColumn(), error.str()); // Error recovery myStack.pop(); // Move past the bad symbol. } } else if (typeid(*expectedSymbol.get()) == typeid(ActionSymbol)) { myStack.pop(); mySemanticRoutines.executeSemanticRoutine(expectedSymbol); } else if (typeid(*expectedSymbol.get()) == typeid(EOPSymbol)) { mySemanticStack.restore(expectedSymbol); myStack.pop(); } if (myPrintParse && ! myEWTracker.hasError()) { std::cout << std::setw(ACTION_WIDTH) << predictValue.str() << " | " << std::setw(TOKENS_WIDTH) << remainingTokens.str() << " | " << std::setw(STACK_WIDTH) << stackContents.str() << std::endl; } printState(token); } }
int main(int argc, char *argv[]) { CGTFile cgtFile; char *source; Symbol *rdc; DFA *dfa; LALR *lalr; ErrorTable *myErrors; SimpleErrorRep myReporter; // Load grammar file if (cgtFile.load ("simple.cgt")) { wprintf (L"%s\n", "Grammar loaded succesfully"); cgtFile.printInfo (); } else { wprintf (L"%s\n", "error loading file"); return -1; } // Load source file char *filename = "test1.s"; source = load_source (filename); if (source == NULL) { wprintf (L"Error loading source file\n"); return -1; } // Get DFA (Deterministic Finite Automata) from the cgt file dfa = cgtFile.getScanner(); // Scan the source in search of tokens dfa->scan(source); delete [] source; // Get the error table myErrors = dfa->getErrors(); // If there are errors report them if (myErrors->errors.size() > 0) { for (unsigned int i=0; i < myErrors->errors.size(); i++) { cout << filename << ":"; cout << myReporter.composeErrorMsg (*myErrors->errors[i]) << endl; } return -1; } // Get the tokens to feed the LALR machine with them vector <Token*> tokens = dfa->getTokens(); printTokens (tokens); // Get the LALR (Look Ahead, Left-to-right parse, Rightmost-derivation) lalr = cgtFile.getParser(); // Parse the tokens rdc = lalr->parse (tokens, true, true); myErrors = lalr->getErrors(); if (myErrors->errors.size() != 0) { for (unsigned int i=0; i < myErrors->errors.size(); i++) { cout << filename << ":"; cout << myReporter.composeErrorMsg (*myErrors->errors[i]) << endl; } return -1; } lalr->printReductionTree(rdc, 0); delete rdc; return EXIT_SUCCESS; }
// This function prints the linked list. void printTokens(Value* value){ if (value && value->type == cellType){ Value *curValue = value; while (curValue->cons->cdr){ if (!curValue->cons->car && (curValue->type != cellType)) { return; } if (!(curValue->type == cellType)) { printToken(curValue); printf(".\n"); printf("):close\n"); return; } if (!(curValue->cons->cdr->type == cellType)){ printToken(curValue->cons->car); printf(".\n"); printToken(curValue->cons->cdr); printf("):close\n"); return; } switch (curValue->cons->car->type) { case booleanType: if(curValue->cons->car->boolValue){ printf("#t:boolean\n"); } else{ printf("#f:boolean\n"); } break; case cellType: printToken(curValue->cons->car); break; case integerType: printf("%d:integer\n",curValue->cons->car->intValue); break; case floatType: printf("%lf:float\n",curValue->cons->car->dblValue); break; case stringType: printf("%s:string\n",curValue->cons->car->stringValue); break; case symbolType: printf("%s:symbol\n",curValue->cons->car->symbolValue); break; case openType: printf("(:open\n"); break; case closeType: printf("):close\n"); break; case nullType: printf("():null\n"); break; default: break; } if (curValue->cons->cdr->type == cellType) { curValue = curValue->cons->cdr; } else { printTokens(curValue->cons->cdr); printf("):close\n"); return; // curValue = curValue->cdr; } } if (curValue) { printToken(curValue->cons->car); } } }