fork download
  1. #pragma warning(push)
  2. #pragma warning(disable: 4365)
  3. #include <vector>
  4. #include <string>
  5. #include <utility>
  6. #pragma warning(pop)
  7.  
  8. using std::string;
  9. using std::vector;
  10. using std::pair;
  11.  
  12. enum class TokenType {
  13. number,
  14. name,
  15. add, substract, multiply, divide, modulo,
  16. factorial,
  17. leftParenthesis, rightParenthesis,
  18. equal,
  19. statementEnding,
  20. quit,
  21. let,
  22. bad,
  23. empty
  24. };
  25.  
  26. class Token {
  27. public:
  28. Token(TokenType type);
  29. Token(TokenType type, string value);
  30.  
  31. double toNumeric();
  32. TokenType getType() const;
  33. string getValue() const;
  34.  
  35. static bool hasCharacterValue(TokenType type);
  36. static string tokenTypeToValue(TokenType type);
  37. static TokenType characterToTokenType(char ch);
  38. static TokenType stringToTokenType(const string& str);
  39.  
  40. private:
  41. TokenType type;
  42. string value;
  43. static const vector<pair<TokenType, char>> tokenTypeToCharacter_pairs;
  44. static const vector<pair<TokenType, string>> tokenTypeToString_pairs;
  45. };
  46.  
  47. /////////////////////////////////////////////////////////////////////////////////
  48.  
  49. //#pragma warning(push)
  50. //#pragma warning(disable: 4365)
  51. #include <string>
  52. #include <stdexcept>
  53. #include <cmath>
  54. #include <utility>
  55. #include <algorithm>
  56. #include <climits>
  57. //#pragma warning(pop)
  58.  
  59. using std::domain_error;
  60. using std::find;
  61. using std::find_if;
  62. using std::string;
  63. using std::stod;
  64. using std::numeric_limits;
  65.  
  66. Token::Token(TokenType type)
  67. : type{ type } {
  68. value = tokenTypeToValue(type);
  69. }
  70.  
  71. Token::Token(TokenType type, string value)
  72. : type{ type }, value{ value } {}
  73.  
  74. double Token::toNumeric() try {
  75. return stod(value);
  76. }
  77. catch (const std::exception&) {
  78. throw domain_error("\"" + value + "\" is not a real number record");
  79. }
  80.  
  81. TokenType Token::getType() const {
  82. return type;
  83. }
  84.  
  85. string Token::getValue() const {
  86. return value;
  87. }
  88.  
  89. const vector<pair<TokenType, char>> Token::tokenTypeToCharacter_pairs = {
  90. {TokenType::add, '+'},
  91. {TokenType::substract, '-'},
  92. {TokenType::multiply, '*'},
  93. {TokenType::divide, '/'},
  94. {TokenType::modulo, '%'},
  95. {TokenType::factorial, '!'},
  96. {TokenType::leftParenthesis, '('},
  97. {TokenType::rightParenthesis, ')'},
  98. {TokenType::equal, '='},
  99. {TokenType::add, '+'},
  100. {TokenType::statementEnding, '='}
  101. };
  102.  
  103. const vector<pair<TokenType, string>> Token::tokenTypeToString_pairs = {
  104. {TokenType::quit, "quit"},
  105. {TokenType::let, "let"},
  106. {TokenType::empty, "empty!"}
  107. };
  108.  
  109. bool Token::hasCharacterValue(TokenType type) {
  110. auto searchAmongCharactersPredicate = [type](const pair<TokenType, char>& p) -> bool {
  111. return p.first == type;
  112. };
  113. auto itChar = find_if(tokenTypeToCharacter_pairs.begin(), tokenTypeToCharacter_pairs.end(), searchAmongCharactersPredicate);
  114. return itChar != tokenTypeToCharacter_pairs.end();
  115. }
  116.  
  117. string Token::tokenTypeToValue(TokenType type) {
  118. auto searchAmongCharactersPredicate = [type](const pair<TokenType, char>& pair) -> bool {
  119. return pair.first == type;
  120. };
  121. auto itChar = find_if(tokenTypeToCharacter_pairs.begin(), tokenTypeToCharacter_pairs.end(), searchAmongCharactersPredicate);
  122. if (itChar != tokenTypeToCharacter_pairs.end()) {
  123. return string() + itChar->second;
  124. }
  125.  
  126. auto searchAmongStringsPredicate = [type](const pair<TokenType, string>& pair) -> bool {
  127. return pair.first == type;
  128. };
  129. auto itString = find_if(tokenTypeToString_pairs.begin(), tokenTypeToString_pairs.end(), searchAmongStringsPredicate);
  130. if (itString != tokenTypeToString_pairs.end()) {
  131. return itString->second;
  132. }
  133. throw domain_error("given token type has no definite value");
  134. }
  135.  
  136. TokenType Token::characterToTokenType(char ch) {
  137. auto searchPredicate =
  138. [ch](const pair<TokenType, char>& pair) -> bool {
  139. return pair.second == ch;
  140. };
  141. auto it = find_if(tokenTypeToCharacter_pairs.begin(), tokenTypeToCharacter_pairs.end(), searchPredicate);
  142. if (it == tokenTypeToCharacter_pairs.end()) {
  143. throw domain_error(string("there is not a token type that represents the character \"") + ch + "\"");
  144. }
  145. else {
  146. return it->first;
  147. }
  148. }
  149.  
  150. TokenType Token::stringToTokenType(const string& str) {
  151. auto searchPredicate =
  152. [str](const pair<TokenType, string>& p) -> bool {
  153. return p.second == str;
  154. };
  155. auto it = find_if(tokenTypeToString_pairs.begin(), tokenTypeToString_pairs.end(), searchPredicate);
  156. if (it == tokenTypeToString_pairs.end()) {
  157. throw domain_error(string("there is not a token type that represents the string \"") + str + "\"");
  158. }
  159. else {
  160. return it->first;
  161. }
  162. }
  163.  
  164. /////////////////////////////////////////////////////////////////////////////////
  165.  
  166. #include <iostream>
  167.  
  168. int main()
  169. {
  170. auto result = Token::tokenTypeToValue(TokenType::empty);
  171. std::cout << result;
  172. }
Success #stdin #stdout 0.01s 5456KB
stdin
Standard input is empty
stdout
empty!