#pragma warning(push)
#pragma warning(disable: 4365)
#include <vector>
#include <string>
#include <utility>
#pragma warning(pop)
using std::string;
using std::vector;
using std::pair;
enum class TokenType {
number,
name,
add, substract, multiply, divide, modulo,
factorial,
leftParenthesis, rightParenthesis,
equal,
statementEnding,
quit,
let,
bad,
empty
};
class Token {
public:
Token(TokenType type);
Token(TokenType type, string value);
double toNumeric();
TokenType getType() const;
string getValue() const;
static bool hasCharacterValue(TokenType type);
static string tokenTypeToValue(TokenType type);
static TokenType characterToTokenType(char ch);
static TokenType stringToTokenType(const string& str);
private:
TokenType type;
string value;
static const vector<pair<TokenType, char>> tokenTypeToCharacter_pairs;
static const vector<pair<TokenType, string>> tokenTypeToString_pairs;
};
/////////////////////////////////////////////////////////////////////////////////
//#pragma warning(push)
//#pragma warning(disable: 4365)
#include <string>
#include <stdexcept>
#include <cmath>
#include <utility>
#include <algorithm>
#include <climits>
//#pragma warning(pop)
using std::domain_error;
using std::find;
using std::find_if;
using std::string;
using std::stod;
using std::numeric_limits;
Token::Token(TokenType type)
: type{ type } {
value = tokenTypeToValue(type);
}
Token::Token(TokenType type, string value)
: type{ type }, value{ value } {}
double Token::toNumeric() try {
return stod(value);
}
catch (const std::exception&) {
throw domain_error("\"" + value + "\" is not a real number record");
}
TokenType Token::getType() const {
return type;
}
string Token::getValue() const {
return value;
}
const vector<pair<TokenType, char>> Token::tokenTypeToCharacter_pairs = {
{TokenType::add, '+'},
{TokenType::substract, '-'},
{TokenType::multiply, '*'},
{TokenType::divide, '/'},
{TokenType::modulo, '%'},
{TokenType::factorial, '!'},
{TokenType::leftParenthesis, '('},
{TokenType::rightParenthesis, ')'},
{TokenType::equal, '='},
{TokenType::add, '+'},
{TokenType::statementEnding, '='}
};
const vector<pair<TokenType, string>> Token::tokenTypeToString_pairs = {
{TokenType::quit, "quit"},
{TokenType::let, "let"},
{TokenType::empty, "empty!"}
};
bool Token::hasCharacterValue(TokenType type) {
auto searchAmongCharactersPredicate = [type](const pair<TokenType, char>& p) -> bool {
return p.first == type;
};
auto itChar = find_if(tokenTypeToCharacter_pairs.begin(), tokenTypeToCharacter_pairs.end(), searchAmongCharactersPredicate);
return itChar != tokenTypeToCharacter_pairs.end();
}
string Token::tokenTypeToValue(TokenType type) {
auto searchAmongCharactersPredicate = [type](const pair<TokenType, char>& pair) -> bool {
return pair.first == type;
};
auto itChar = find_if(tokenTypeToCharacter_pairs.begin(), tokenTypeToCharacter_pairs.end(), searchAmongCharactersPredicate);
if (itChar != tokenTypeToCharacter_pairs.end()) {
return string() + itChar->second;
}
auto searchAmongStringsPredicate = [type](const pair<TokenType, string>& pair) -> bool {
return pair.first == type;
};
auto itString = find_if(tokenTypeToString_pairs.begin(), tokenTypeToString_pairs.end(), searchAmongStringsPredicate);
if (itString != tokenTypeToString_pairs.end()) {
return itString->second;
}
throw domain_error("given token type has no definite value");
}
TokenType Token::characterToTokenType(char ch) {
auto searchPredicate =
[ch](const pair<TokenType, char>& pair) -> bool {
return pair.second == ch;
};
auto it = find_if(tokenTypeToCharacter_pairs.begin(), tokenTypeToCharacter_pairs.end(), searchPredicate);
if (it == tokenTypeToCharacter_pairs.end()) {
throw domain_error(string("there is not a token type that represents the character \"") + ch + "\"");
}
else {
return it->first;
}
}
TokenType Token::stringToTokenType(const string& str) {
auto searchPredicate =
[str](const pair<TokenType, string>& p) -> bool {
return p.second == str;
};
auto it = find_if(tokenTypeToString_pairs.begin(), tokenTypeToString_pairs.end(), searchPredicate);
if (it == tokenTypeToString_pairs.end()) {
throw domain_error(string("there is not a token type that represents the string \"") + str + "\"");
}
else {
return it->first;
}
}
/////////////////////////////////////////////////////////////////////////////////
#include <iostream>
int main()
{
auto result = Token::tokenTypeToValue(TokenType::empty);
std::cout << result;
}
I3ByYWdtYSB3YXJuaW5nKHB1c2gpCiNwcmFnbWEgd2FybmluZyhkaXNhYmxlOiA0MzY1KQojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8dXRpbGl0eT4KI3ByYWdtYSB3YXJuaW5nKHBvcCkKCnVzaW5nIHN0ZDo6c3RyaW5nOwp1c2luZyBzdGQ6OnZlY3RvcjsKdXNpbmcgc3RkOjpwYWlyOwoKZW51bSBjbGFzcyBUb2tlblR5cGUgewoJbnVtYmVyLAoJbmFtZSwKCWFkZCwgc3Vic3RyYWN0LCBtdWx0aXBseSwgZGl2aWRlLCBtb2R1bG8sCglmYWN0b3JpYWwsCglsZWZ0UGFyZW50aGVzaXMsIHJpZ2h0UGFyZW50aGVzaXMsCgllcXVhbCwKCXN0YXRlbWVudEVuZGluZywKCXF1aXQsCglsZXQsCgliYWQsCgllbXB0eQp9OwoKY2xhc3MgVG9rZW4gewpwdWJsaWM6CglUb2tlbihUb2tlblR5cGUgdHlwZSk7CglUb2tlbihUb2tlblR5cGUgdHlwZSwgc3RyaW5nIHZhbHVlKTsKCglkb3VibGUgdG9OdW1lcmljKCk7CglUb2tlblR5cGUgZ2V0VHlwZSgpIGNvbnN0OwoJc3RyaW5nIGdldFZhbHVlKCkgY29uc3Q7CgoJc3RhdGljIGJvb2wgaGFzQ2hhcmFjdGVyVmFsdWUoVG9rZW5UeXBlIHR5cGUpOwoJc3RhdGljIHN0cmluZyB0b2tlblR5cGVUb1ZhbHVlKFRva2VuVHlwZSB0eXBlKTsKCXN0YXRpYyBUb2tlblR5cGUgY2hhcmFjdGVyVG9Ub2tlblR5cGUoY2hhciBjaCk7CglzdGF0aWMgVG9rZW5UeXBlIHN0cmluZ1RvVG9rZW5UeXBlKGNvbnN0IHN0cmluZyYgc3RyKTsKCnByaXZhdGU6CglUb2tlblR5cGUgdHlwZTsKCXN0cmluZyB2YWx1ZTsKCXN0YXRpYyBjb25zdCB2ZWN0b3I8cGFpcjxUb2tlblR5cGUsIGNoYXI+PiB0b2tlblR5cGVUb0NoYXJhY3Rlcl9wYWlyczsKCXN0YXRpYyBjb25zdCB2ZWN0b3I8cGFpcjxUb2tlblR5cGUsIHN0cmluZz4+IHRva2VuVHlwZVRvU3RyaW5nX3BhaXJzOwp9OwoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgovLyNwcmFnbWEgd2FybmluZyhwdXNoKQovLyNwcmFnbWEgd2FybmluZyhkaXNhYmxlOiA0MzY1KQojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8c3RkZXhjZXB0PgojaW5jbHVkZSA8Y21hdGg+CiNpbmNsdWRlIDx1dGlsaXR5PgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8Y2xpbWl0cz4KLy8jcHJhZ21hIHdhcm5pbmcocG9wKQoKdXNpbmcgc3RkOjpkb21haW5fZXJyb3I7CnVzaW5nIHN0ZDo6ZmluZDsKdXNpbmcgc3RkOjpmaW5kX2lmOwp1c2luZyBzdGQ6OnN0cmluZzsKdXNpbmcgc3RkOjpzdG9kOwp1c2luZyBzdGQ6Om51bWVyaWNfbGltaXRzOwoKVG9rZW46OlRva2VuKFRva2VuVHlwZSB0eXBlKQoJOiB0eXBleyB0eXBlIH0gewoJdmFsdWUgPSB0b2tlblR5cGVUb1ZhbHVlKHR5cGUpOwp9CgpUb2tlbjo6VG9rZW4oVG9rZW5UeXBlIHR5cGUsIHN0cmluZyB2YWx1ZSkKCTogdHlwZXsgdHlwZSB9LCB2YWx1ZXsgdmFsdWUgfSB7fQoKZG91YmxlIFRva2VuOjp0b051bWVyaWMoKSB0cnkgewoJcmV0dXJuIHN0b2QodmFsdWUpOwp9CmNhdGNoIChjb25zdCBzdGQ6OmV4Y2VwdGlvbiYpIHsKCXRocm93IGRvbWFpbl9lcnJvcigiXCIiICsgdmFsdWUgKyAiXCIgaXMgbm90IGEgcmVhbCBudW1iZXIgcmVjb3JkIik7Cn0KClRva2VuVHlwZSBUb2tlbjo6Z2V0VHlwZSgpIGNvbnN0IHsKCXJldHVybiB0eXBlOwp9CgpzdHJpbmcgVG9rZW46OmdldFZhbHVlKCkgY29uc3QgewoJcmV0dXJuIHZhbHVlOwp9Cgpjb25zdCB2ZWN0b3I8cGFpcjxUb2tlblR5cGUsIGNoYXI+PiBUb2tlbjo6dG9rZW5UeXBlVG9DaGFyYWN0ZXJfcGFpcnMgPSB7CgkJe1Rva2VuVHlwZTo6YWRkLCAnKyd9LAoJCXtUb2tlblR5cGU6OnN1YnN0cmFjdCwgJy0nfSwKCQl7VG9rZW5UeXBlOjptdWx0aXBseSwgJyonfSwKCQl7VG9rZW5UeXBlOjpkaXZpZGUsICcvJ30sCgkJe1Rva2VuVHlwZTo6bW9kdWxvLCAnJSd9LAoJCXtUb2tlblR5cGU6OmZhY3RvcmlhbCwgJyEnfSwKCQl7VG9rZW5UeXBlOjpsZWZ0UGFyZW50aGVzaXMsICcoJ30sCgkJe1Rva2VuVHlwZTo6cmlnaHRQYXJlbnRoZXNpcywgJyknfSwKCQl7VG9rZW5UeXBlOjplcXVhbCwgJz0nfSwKCQl7VG9rZW5UeXBlOjphZGQsICcrJ30sCgkJe1Rva2VuVHlwZTo6c3RhdGVtZW50RW5kaW5nLCAnPSd9Cn07Cgpjb25zdCB2ZWN0b3I8cGFpcjxUb2tlblR5cGUsIHN0cmluZz4+IFRva2VuOjp0b2tlblR5cGVUb1N0cmluZ19wYWlycyA9IHsKCXtUb2tlblR5cGU6OnF1aXQsICJxdWl0In0sCgl7VG9rZW5UeXBlOjpsZXQsICJsZXQifSwKCXtUb2tlblR5cGU6OmVtcHR5LCAiZW1wdHkhIn0KfTsKCmJvb2wgVG9rZW46Omhhc0NoYXJhY3RlclZhbHVlKFRva2VuVHlwZSB0eXBlKSB7CglhdXRvIHNlYXJjaEFtb25nQ2hhcmFjdGVyc1ByZWRpY2F0ZSA9IFt0eXBlXShjb25zdCBwYWlyPFRva2VuVHlwZSwgY2hhcj4mIHApIC0+IGJvb2wgewoJCXJldHVybiBwLmZpcnN0ID09IHR5cGU7Cgl9OwoJYXV0byBpdENoYXIgPSBmaW5kX2lmKHRva2VuVHlwZVRvQ2hhcmFjdGVyX3BhaXJzLmJlZ2luKCksIHRva2VuVHlwZVRvQ2hhcmFjdGVyX3BhaXJzLmVuZCgpLCBzZWFyY2hBbW9uZ0NoYXJhY3RlcnNQcmVkaWNhdGUpOwoJcmV0dXJuIGl0Q2hhciAhPSB0b2tlblR5cGVUb0NoYXJhY3Rlcl9wYWlycy5lbmQoKTsKfQoKc3RyaW5nIFRva2VuOjp0b2tlblR5cGVUb1ZhbHVlKFRva2VuVHlwZSB0eXBlKSB7CglhdXRvIHNlYXJjaEFtb25nQ2hhcmFjdGVyc1ByZWRpY2F0ZSA9IFt0eXBlXShjb25zdCBwYWlyPFRva2VuVHlwZSwgY2hhcj4mIHBhaXIpIC0+IGJvb2wgewoJCXJldHVybiBwYWlyLmZpcnN0ID09IHR5cGU7Cgl9OwoJYXV0byBpdENoYXIgPSBmaW5kX2lmKHRva2VuVHlwZVRvQ2hhcmFjdGVyX3BhaXJzLmJlZ2luKCksIHRva2VuVHlwZVRvQ2hhcmFjdGVyX3BhaXJzLmVuZCgpLCBzZWFyY2hBbW9uZ0NoYXJhY3RlcnNQcmVkaWNhdGUpOwoJaWYgKGl0Q2hhciAhPSB0b2tlblR5cGVUb0NoYXJhY3Rlcl9wYWlycy5lbmQoKSkgewoJCXJldHVybiBzdHJpbmcoKSArIGl0Q2hhci0+c2Vjb25kOwoJfQoKCWF1dG8gc2VhcmNoQW1vbmdTdHJpbmdzUHJlZGljYXRlID0gW3R5cGVdKGNvbnN0IHBhaXI8VG9rZW5UeXBlLCBzdHJpbmc+JiBwYWlyKSAtPiBib29sIHsKCQlyZXR1cm4gcGFpci5maXJzdCA9PSB0eXBlOwoJfTsKCWF1dG8gaXRTdHJpbmcgPSBmaW5kX2lmKHRva2VuVHlwZVRvU3RyaW5nX3BhaXJzLmJlZ2luKCksIHRva2VuVHlwZVRvU3RyaW5nX3BhaXJzLmVuZCgpLCBzZWFyY2hBbW9uZ1N0cmluZ3NQcmVkaWNhdGUpOwoJaWYgKGl0U3RyaW5nICE9IHRva2VuVHlwZVRvU3RyaW5nX3BhaXJzLmVuZCgpKSB7CgkJcmV0dXJuIGl0U3RyaW5nLT5zZWNvbmQ7Cgl9Cgl0aHJvdyBkb21haW5fZXJyb3IoImdpdmVuIHRva2VuIHR5cGUgaGFzIG5vIGRlZmluaXRlIHZhbHVlIik7Cn0KClRva2VuVHlwZSBUb2tlbjo6Y2hhcmFjdGVyVG9Ub2tlblR5cGUoY2hhciBjaCkgewoJYXV0byBzZWFyY2hQcmVkaWNhdGUgPQoJCVtjaF0oY29uc3QgcGFpcjxUb2tlblR5cGUsIGNoYXI+JiBwYWlyKSAtPiBib29sIHsKCQlyZXR1cm4gcGFpci5zZWNvbmQgPT0gY2g7Cgl9OwoJYXV0byBpdCA9IGZpbmRfaWYodG9rZW5UeXBlVG9DaGFyYWN0ZXJfcGFpcnMuYmVnaW4oKSwgdG9rZW5UeXBlVG9DaGFyYWN0ZXJfcGFpcnMuZW5kKCksIHNlYXJjaFByZWRpY2F0ZSk7CglpZiAoaXQgPT0gdG9rZW5UeXBlVG9DaGFyYWN0ZXJfcGFpcnMuZW5kKCkpIHsKCQl0aHJvdyBkb21haW5fZXJyb3Ioc3RyaW5nKCJ0aGVyZSBpcyBub3QgYSB0b2tlbiB0eXBlIHRoYXQgcmVwcmVzZW50cyB0aGUgY2hhcmFjdGVyIFwiIikgKyBjaCArICJcIiIpOwoJfQoJZWxzZSB7CgkJcmV0dXJuIGl0LT5maXJzdDsKCX0KfQoKVG9rZW5UeXBlIFRva2VuOjpzdHJpbmdUb1Rva2VuVHlwZShjb25zdCBzdHJpbmcmIHN0cikgewoJYXV0byBzZWFyY2hQcmVkaWNhdGUgPQoJCVtzdHJdKGNvbnN0IHBhaXI8VG9rZW5UeXBlLCBzdHJpbmc+JiBwKSAtPiBib29sIHsKCQlyZXR1cm4gcC5zZWNvbmQgPT0gc3RyOwoJfTsKCWF1dG8gaXQgPSBmaW5kX2lmKHRva2VuVHlwZVRvU3RyaW5nX3BhaXJzLmJlZ2luKCksIHRva2VuVHlwZVRvU3RyaW5nX3BhaXJzLmVuZCgpLCBzZWFyY2hQcmVkaWNhdGUpOwoJaWYgKGl0ID09IHRva2VuVHlwZVRvU3RyaW5nX3BhaXJzLmVuZCgpKSB7CgkJdGhyb3cgZG9tYWluX2Vycm9yKHN0cmluZygidGhlcmUgaXMgbm90IGEgdG9rZW4gdHlwZSB0aGF0IHJlcHJlc2VudHMgdGhlIHN0cmluZyBcIiIpICsgc3RyICsgIlwiIik7Cgl9CgllbHNlIHsKCQlyZXR1cm4gaXQtPmZpcnN0OwoJfQp9CgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCiNpbmNsdWRlIDxpb3N0cmVhbT4KCmludCBtYWluKCkKewoJYXV0byByZXN1bHQgPSAgVG9rZW46OnRva2VuVHlwZVRvVmFsdWUoVG9rZW5UeXBlOjplbXB0eSk7CiAgICBzdGQ6OmNvdXQgPDwgcmVzdWx0OyAKfQ==