upd: first version of lexer
This commit is contained in:
@ -5,6 +5,7 @@
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
|
||||
#include "bs-utility.h"
|
||||
#include "engine.h"
|
||||
@ -12,7 +13,7 @@ void BookStoreMain(bool is_server, std::string config_dir) {
|
||||
BookStoreEngineClass engine(config_dir, is_server);
|
||||
std::ios::sync_with_stdio(false);
|
||||
if (!is_server) {
|
||||
std::stack<std::string> login_stack;
|
||||
std::stack<std::pair<std::string, std::string>> login_stack;
|
||||
std::string cmd;
|
||||
while (std::getline(std::cin, cmd)) {
|
||||
auto result = std::move(engine.Execute(cmd, login_stack));
|
||||
|
@ -3,4 +3,14 @@
|
||||
void UserDataBase::Open(std::string file_name) {
|
||||
full_user_data.OpenFile(file_name + ".full");
|
||||
user_name2index.OpenFile(file_name + ".n2i");
|
||||
}
|
||||
|
||||
void BookDataBase::Open(std::string file_name) {
|
||||
full_book_data.OpenFile(file_name + ".full");
|
||||
indexer.OpenFile(file_name + ".n2i");
|
||||
}
|
||||
|
||||
void LogDataBase::Open(std::string file_name) {
|
||||
finance_data.OpenFile(file_name + ".finance");
|
||||
operation_log_data.OpenFile(file_name + ".log");
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
#include "engine.h"
|
||||
|
||||
#include <cctype>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
@ -10,10 +11,15 @@ BookStoreEngineClass::BookStoreEngineClass(std::string __config_dir,
|
||||
bool __is_server) {
|
||||
config_dir = __config_dir;
|
||||
user_data_base.Open(config_dir + "user");
|
||||
book_data_base.Open(config_dir + "book");
|
||||
log_data_base.Open(config_dir + "log");
|
||||
is_server = __is_server;
|
||||
}
|
||||
std::vector<std::string> BookStoreEngineClass::Execute(
|
||||
const std::string &cmd, std::stack<std::string> &login_stack) {
|
||||
const std::string &cmd, std::stack<std::pair<std::string, std::string>> &login_stack) {
|
||||
for (int i = 0; i < cmd.length(); i++)
|
||||
if (std::isspace(cmd[i]) && cmd[i] != ' ')
|
||||
return std::vector<std::string>({"Invalid"});
|
||||
static std::unordered_map<std::string, OperationType> operation_map = {
|
||||
{"su", OperationType::__Ksu},
|
||||
{"logout", OperationType::__Klogout},
|
||||
@ -42,38 +48,123 @@ std::vector<std::string> BookStoreEngineClass::Execute(
|
||||
}
|
||||
switch (operation_map[head]) {
|
||||
case OperationType::__Ksu: {
|
||||
return ExecuteSu(cmd, login_stack);
|
||||
}
|
||||
case OperationType::__Klogout: {
|
||||
return ExecuteLogout(cmd, login_stack);
|
||||
}
|
||||
case OperationType::__Kuseradd: {
|
||||
return ExecuteUserAdd(cmd, login_stack);
|
||||
}
|
||||
case OperationType::__Kregister: {
|
||||
return ExecuteRegister(cmd, login_stack);
|
||||
}
|
||||
case OperationType::__Kdelete: {
|
||||
return ExecuteDelete(cmd, login_stack);
|
||||
}
|
||||
case OperationType::__Kpasswd: {
|
||||
return ExecutePasswd(cmd, login_stack);
|
||||
}
|
||||
case OperationType::__Kselect: {
|
||||
return ExecuteSelect(cmd, login_stack);
|
||||
}
|
||||
case OperationType::__Kmodify: {
|
||||
return ExecuteMOdify(cmd, login_stack);
|
||||
}
|
||||
case OperationType::__Kimport: {
|
||||
return ExecuteImport(cmd, login_stack);
|
||||
}
|
||||
case OperationType::__Kshow: {
|
||||
ss >> head;
|
||||
if (head == "finance") goto dst_showfinance;
|
||||
return ExecuteShow(cmd, login_stack);
|
||||
}
|
||||
case OperationType::__Kshowfinance: {
|
||||
dst_showfinance:;
|
||||
return ExecuteShowFinance(cmd, login_stack);
|
||||
}
|
||||
case OperationType::__Kbuy: {
|
||||
return ExecuteBuy(cmd, login_stack);
|
||||
}
|
||||
case OperationType::__Kreport: {
|
||||
throw FatalError("report Not implemented", 2);
|
||||
// throw FatalError("report Not implemented", 2);
|
||||
return ExecuteReport(cmd, login_stack);
|
||||
}
|
||||
case OperationType::__Klog: {
|
||||
throw FatalError("log Not implemented", 3);
|
||||
// throw FatalError("log Not implemented", 3);
|
||||
return ExecuteLog(cmd, login_stack);
|
||||
}
|
||||
}
|
||||
throw FatalError("Unknown Command", 5);
|
||||
return std::vector<std::string>({cmd});
|
||||
}
|
||||
|
||||
std::vector<std::string> BookStoreEngineClass::ExecuteSu(
|
||||
const std::string &cmd, std::stack<std::pair<std::string, std::string>> &login_stack) {
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
|
||||
std::vector<std::string> BookStoreEngineClass::ExecuteLogout(
|
||||
const std::string &cmd, std::stack<std::pair<std::string, std::string>> &login_stack) {
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
|
||||
std::vector<std::string> BookStoreEngineClass::ExecuteRegister(
|
||||
const std::string &cmd, std::stack<std::pair<std::string, std::string>> &login_stack) {
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
|
||||
std::vector<std::string> BookStoreEngineClass::ExecutePasswd(
|
||||
const std::string &cmd, std::stack<std::pair<std::string, std::string>> &login_stack) {
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
|
||||
std::vector<std::string> BookStoreEngineClass::ExecuteUserAdd(
|
||||
const std::string &cmd, std::stack<std::pair<std::string, std::string>> &login_stack) {
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
|
||||
std::vector<std::string> BookStoreEngineClass::ExecuteDelete(
|
||||
const std::string &cmd, std::stack<std::pair<std::string, std::string>> &login_stack) {
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
|
||||
std::vector<std::string> BookStoreEngineClass::ExecuteShow(
|
||||
const std::string &cmd, std::stack<std::pair<std::string, std::string>> &login_stack) {
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
|
||||
std::vector<std::string> BookStoreEngineClass::ExecuteBuy(
|
||||
const std::string &cmd, std::stack<std::pair<std::string, std::string>> &login_stack) {
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
|
||||
std::vector<std::string> BookStoreEngineClass::ExecuteSelect(
|
||||
const std::string &cmd, std::stack<std::pair<std::string, std::string>> &login_stack) {
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
|
||||
std::vector<std::string> BookStoreEngineClass::ExecuteMOdify(
|
||||
const std::string &cmd, std::stack<std::pair<std::string, std::string>> &login_stack) {
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
|
||||
std::vector<std::string> BookStoreEngineClass::ExecuteImport(
|
||||
const std::string &cmd, std::stack<std::pair<std::string, std::string>> &login_stack) {
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
|
||||
std::vector<std::string> BookStoreEngineClass::ExecuteShowFinance(
|
||||
const std::string &cmd, std::stack<std::pair<std::string, std::string>> &login_stack) {
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
|
||||
std::vector<std::string> BookStoreEngineClass::ExecuteLog(
|
||||
const std::string &cmd, std::stack<std::pair<std::string, std::string>> &login_stack) {
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
|
||||
std::vector<std::string> BookStoreEngineClass::ExecuteReport(
|
||||
const std::string &cmd, std::stack<std::pair<std::string, std::string>> &login_stack) {
|
||||
return std::vector<std::string>();
|
||||
}
|
@ -1,4 +1,210 @@
|
||||
#include "lexer.h"
|
||||
|
||||
// clang-format off
|
||||
/**
|
||||
* @brief Lexer for command "su"
|
||||
*
|
||||
* @param command The command to be parsed
|
||||
* @param user_id The user_id to be logged in
|
||||
* @param password The password to be logged in
|
||||
*
|
||||
* @return true if the command is valid
|
||||
*
|
||||
* @note The command is valid if and only if it follows the following grammar:
|
||||
* su [UserID] ([Password])?
|
||||
*/
|
||||
// clang-format on
|
||||
bool CommandSuLexer(const std::string &command, std::string &user_id,
|
||||
std::string &password) {
|
||||
static std::basic_regex main_pattern(
|
||||
R"(^ *su +(?:[0-9a-zA-Z_]{1,30}) +(?:[0-9a-zA-Z_]{1,30})? *$)",
|
||||
std::regex_constants::optimize);
|
||||
if (std::regex_match(command, main_pattern)) {
|
||||
std::stringstream ss(command);
|
||||
std::string token;
|
||||
ss >> token;
|
||||
user_id = "";
|
||||
password = "";
|
||||
ss >> user_id;
|
||||
ss >> password;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
/**
|
||||
* @brief Lexer for command "logout"
|
||||
*
|
||||
* @param command The command to be parsed
|
||||
*
|
||||
* @return true if the command is valid
|
||||
*
|
||||
* @note The command is valid if and only if it follows the following grammar:
|
||||
* logout
|
||||
*/
|
||||
// clang-format on
|
||||
bool CommandLogoutLexer(const std::string &command) {
|
||||
static std::basic_regex main_pattern(R"(^ *logout *$)",
|
||||
std::regex_constants::optimize);
|
||||
return std::regex_match(command, main_pattern);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
/**
|
||||
* @brief Lexer for command "register"
|
||||
*
|
||||
* @param command The command to be parsed
|
||||
* @param user_id The user_id to be registered
|
||||
* @param password The password to be registered
|
||||
*
|
||||
* @return true if the command is valid
|
||||
*
|
||||
* @note The command is valid if and only if it follows the following grammar:
|
||||
* register [UserID] [Password] [Username]
|
||||
*/
|
||||
// clang-format on
|
||||
bool CommandRegisterLexer(const std::string &command, std::string &user_id,
|
||||
std::string &password, std::string &username) {
|
||||
static std::basic_regex main_pattern(
|
||||
R"(^ *register +(?:[0-9a-zA-Z_]{1,30}) +(?:[0-9a-zA-Z_]{1,30}) +(?:[^\s]{1,30}) *$)",
|
||||
std::regex_constants::optimize);
|
||||
if (std::regex_match(command, main_pattern)) {
|
||||
std::stringstream ss(command);
|
||||
std::string token;
|
||||
ss >> token;
|
||||
user_id = "";
|
||||
password = "";
|
||||
username = "";
|
||||
ss >> user_id;
|
||||
ss >> password;
|
||||
ss >> username;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
/**
|
||||
* @brief Lexer for command "passwd"
|
||||
*
|
||||
* @param command The command to be parsed
|
||||
* @param user_id The user_id to be changed password
|
||||
* @param old_password The old password
|
||||
* @param new_password The new password
|
||||
*
|
||||
* @return true if the command is valid
|
||||
*
|
||||
* @note The command is valid if and only if it follows the following grammar:
|
||||
* passwd [UserID] ([CurrentPassword])? [NewPassword]
|
||||
*/
|
||||
// clang-format on
|
||||
bool CommandPasswdLexer(const std::string &command, std::string &user_id,
|
||||
std::string &old_password, std::string &new_password) {
|
||||
static std::basic_regex main_pattern(
|
||||
R"(^ *passwd +(?:[0-9a-zA-Z_]{1,30}) +(?:[0-9a-zA-Z_]{1,30})? +(?:[0-9a-zA-Z_]{1,30}) *$)",
|
||||
std::regex_constants::optimize);
|
||||
if (std::regex_match(command, main_pattern)) {
|
||||
std::stringstream ss(command);
|
||||
std::string token;
|
||||
ss >> token;
|
||||
user_id = "";
|
||||
old_password = "";
|
||||
new_password = "";
|
||||
ss >> user_id;
|
||||
ss >> old_password;
|
||||
ss >> new_password;
|
||||
if (new_password == "") {
|
||||
new_password = old_password;
|
||||
old_password = "";
|
||||
}
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
/**
|
||||
* @brief Lexer for command "useradd"
|
||||
*
|
||||
* @param command The command to be parsed
|
||||
* @param user_id The user_id to be added
|
||||
* @param password The password to be added
|
||||
* @param privilege The privilege to be added
|
||||
*
|
||||
* @return true if the command is valid
|
||||
*
|
||||
* @note The command is valid if and only if it follows the following grammar:
|
||||
* useradd [UserID] [Password] [Privilege] [Username]
|
||||
*/
|
||||
// clang-format on
|
||||
bool CommandUseraddLexer(const std::string &command, std::string &user_id,
|
||||
std::string &password, int &privilege,
|
||||
std::string &username) {
|
||||
static std::basic_regex main_pattern(
|
||||
R"(^ *useradd +(?:[0-9a-zA-Z_]{1,30}) +(?:[0-9a-zA-Z_]{1,30}) +[0-9] +(?:[^\s]{1,30}) *$)",
|
||||
std::regex_constants::optimize);
|
||||
if (std::regex_match(command, main_pattern)) {
|
||||
std::stringstream ss(command);
|
||||
std::string token;
|
||||
ss >> token;
|
||||
user_id = "";
|
||||
password = "";
|
||||
privilege = 0;
|
||||
username = "";
|
||||
ss >> user_id;
|
||||
ss >> password;
|
||||
ss >> privilege;
|
||||
ss >> username;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
/**
|
||||
* @brief Lexer for command "delete"
|
||||
*
|
||||
* @param command The command to be parsed
|
||||
* @param user_id The user_id to be deleted
|
||||
*
|
||||
* @return true if the command is valid
|
||||
*
|
||||
* @note The command is valid if and only if it follows the following grammar:
|
||||
* delete [UserID]
|
||||
*/
|
||||
// clang-format on
|
||||
bool CommandDeleteLexer(const std::string &command, std::string &user_id) {
|
||||
static std::basic_regex main_pattern(
|
||||
R"(^ *delete +(?:[0-9a-zA-Z_]{1,30}) *$)",
|
||||
std::regex_constants::optimize);
|
||||
if (std::regex_match(command, main_pattern)) {
|
||||
std::stringstream ss(command);
|
||||
std::string token;
|
||||
ss >> token;
|
||||
user_id = "";
|
||||
ss >> user_id;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
/**
|
||||
* @brief Lexer for command "show"
|
||||
*
|
||||
* @param command The command to be parsed
|
||||
* @param ISBN The ISBN of the book to be shown
|
||||
* @param name The name of the book to be shown
|
||||
* @param author The author of the book to be shown
|
||||
* @param keyword The keyword of the book to be shown
|
||||
*
|
||||
* @return true if the command is valid
|
||||
*
|
||||
* @note The command is valid if and only if it follows the following grammar:
|
||||
* show (-ISBN=[ISBN] | -name="[BookName]" | -author="[Author]" | -keyword="[Keyword]")?
|
||||
*/
|
||||
// clang-format on
|
||||
bool CommandShowLexer(const std::string &command, std::string &ISBN,
|
||||
std::string &name, std::string &author,
|
||||
std::string &keyword) {
|
||||
@ -6,7 +212,6 @@ bool CommandShowLexer(const std::string &command, std::string &ISBN,
|
||||
R"(^ *show(?: +-ISBN=(?:\S{1,20})| +-name=\"(?:[^\s"]{1,60})\"| +-author=\"(?:[^\s"]{1,60})\"| +-keyword=\"(?:[^\s"]{1,60})\")* *$)",
|
||||
std::regex_constants::optimize);
|
||||
|
||||
std::smatch results;
|
||||
bool has_ISBN = false;
|
||||
bool has_name = false;
|
||||
bool has_author = false;
|
||||
@ -15,7 +220,7 @@ bool CommandShowLexer(const std::string &command, std::string &ISBN,
|
||||
name = "";
|
||||
author = "";
|
||||
keyword = "";
|
||||
if (std::regex_match(command, results, main_pattern)) {
|
||||
if (std::regex_match(command, main_pattern)) {
|
||||
std::stringstream ss(command);
|
||||
std::string token;
|
||||
ss >> token;
|
||||
@ -39,6 +244,180 @@ bool CommandShowLexer(const std::string &command, std::string &ISBN,
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < keyword.length(); i++)
|
||||
if (keyword[i] == '|') return false;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
/**
|
||||
* @brief Lexer for command "buy"
|
||||
*
|
||||
* @param command The command to be parsed
|
||||
* @param ISBN The ISBN of the book to be bought
|
||||
* @param quantity The quantity of the book to be bought
|
||||
*
|
||||
* @return true if the command is valid
|
||||
*
|
||||
* @note The command is valid if and only if it follows the following grammar:
|
||||
* buy [ISBN] [Quantity]
|
||||
*/
|
||||
// clang-format on
|
||||
bool CommandBuyLexer(const std::string &command, std::string &ISBN,
|
||||
int &quantity) {
|
||||
static std::basic_regex main_pattern(
|
||||
R"(^ *buy +(?:\S{1,20}) +[0-9]{1,10} *$)",
|
||||
std::regex_constants::optimize);
|
||||
if (std::regex_match(command, main_pattern)) {
|
||||
std::stringstream ss(command);
|
||||
std::string token;
|
||||
ss >> token;
|
||||
ISBN = "";
|
||||
quantity = 0;
|
||||
ss >> ISBN;
|
||||
ss >> quantity;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
/**
|
||||
* @brief Lexer for command "select"
|
||||
*
|
||||
* @param command The command to be parsed
|
||||
* @param ISBN The ISBN of the book to be selected
|
||||
*
|
||||
* @return true if the command is valid
|
||||
*
|
||||
* @note The command is valid if and only if it follows the following grammar:
|
||||
* select [ISBN]
|
||||
*/
|
||||
// clang-format on
|
||||
bool CommandSelectLexer(const std::string &command, std::string &ISBN) {
|
||||
static std::basic_regex main_pattern(R"(^ *select +(?:\S{1,20}) *$)",
|
||||
std::regex_constants::optimize);
|
||||
if (std::regex_match(command, main_pattern)) {
|
||||
std::stringstream ss(command);
|
||||
std::string token;
|
||||
ss >> token;
|
||||
ISBN = "";
|
||||
ss >> ISBN;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
/**
|
||||
* @brief Lexer for command "modify"
|
||||
*
|
||||
* @param command The command to be parsed
|
||||
* @param ISBN The ISBN of the book to be modified
|
||||
* @param name The name of the book to be modified
|
||||
* @param author The author of the book to be modified
|
||||
* @param keyword The keyword of the book to be modified
|
||||
* @param price The price of the book to be modified
|
||||
*
|
||||
* @return true if the command is valid
|
||||
*
|
||||
* @note The command is valid if and only if it follows the following grammar:
|
||||
* modify (-ISBN=[ISBN] | -name="[BookName]" | -author="[Author]" | -keyword="[Keyword]" | -price=[Price])+
|
||||
*/
|
||||
// clang-format on
|
||||
bool CommandModifyLexer(const std::string &command, std::string &ISBN,
|
||||
std::string &name, std::string &author,
|
||||
std::string &keyword, double &price) {
|
||||
static std::basic_regex main_pattern(
|
||||
R"(^ *modify(?: +-ISBN=(?:\S{1,20})| +-name=\"(?:[^\s"]{1,60})\"| +-author=\"(?:[^\s"]{1,60})\"| +-keyword=\"(?:[^\s"]{1,60})\"| +-price=[0-9]{1,10}\.[0-9]{2})+ *$)",
|
||||
std::regex_constants::optimize);
|
||||
if (std::regex_match(command, main_pattern)) {
|
||||
std::stringstream ss(command);
|
||||
std::string token;
|
||||
ss >> token;
|
||||
ISBN = "";
|
||||
name = "";
|
||||
author = "";
|
||||
keyword = "";
|
||||
price = 0;
|
||||
while (ss >> token) {
|
||||
if (token[1] == 'I') {
|
||||
ISBN = token.substr(6);
|
||||
} else if (token[1] == 'n') {
|
||||
name = token.substr(6 + 1, token.size() - 7 - 1);
|
||||
} else if (token[1] == 'a') {
|
||||
author = token.substr(8 + 1, token.size() - 9 - 1);
|
||||
} else if (token[1] == 'k') {
|
||||
keyword = token.substr(9 + 1, token.size() - 10 - 1);
|
||||
} else if (token[1] == 'p') {
|
||||
price = std::stod(token.substr(7));
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < keyword.length(); i++)
|
||||
if (keyword[i] == '|') return false;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
/**
|
||||
* @brief Lexer for command "import"
|
||||
*
|
||||
* @param command The command to be parsed
|
||||
* @param quantity The quantity of the book to be imported
|
||||
* @param total_cost The total cost of the book to be imported
|
||||
*
|
||||
* @return true if the command is valid
|
||||
*
|
||||
* @note The command is valid if and only if it follows the following grammar:
|
||||
* import [Quantity] [TotalCost]
|
||||
*/
|
||||
// clang-format on
|
||||
bool CommandImportLexer(const std::string &command, int &quantity,
|
||||
double &total_cost) {
|
||||
static std::basic_regex main_pattern(
|
||||
R"(^ *import +[0-9]{1,10} +[0-9]{1,10}\.[0-9]{2} *$)",
|
||||
std::regex_constants::optimize);
|
||||
if (std::regex_match(command, main_pattern)) {
|
||||
std::stringstream ss(command);
|
||||
std::string token;
|
||||
ss >> token;
|
||||
quantity = 0;
|
||||
total_cost = 0;
|
||||
ss >> quantity;
|
||||
ss >> total_cost;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
/**
|
||||
* @brief Lexer for command "showfinance"
|
||||
*
|
||||
* @param command The command to be parsed
|
||||
* @param count The count of the finance to be shown
|
||||
*
|
||||
* @return true if the command is valid
|
||||
*
|
||||
* @note The command is valid if and only if it follows the following grammar:
|
||||
* show finance ([Count])?
|
||||
*/
|
||||
// clang-format on
|
||||
bool CommandShowfinanceLexer(const std::string &command, int &count) {
|
||||
static std::basic_regex main_pattern(
|
||||
R"(^ *show +finance(?: +[0-9]{1,10})? *$)",
|
||||
std::regex_constants::optimize);
|
||||
if (std::regex_match(command, main_pattern)) {
|
||||
std::stringstream ss(command);
|
||||
std::string token;
|
||||
ss >> token;
|
||||
count = -1;
|
||||
ss >> count;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
|
Reference in New Issue
Block a user