#include <algorithm>
#include <iostream>
#include <regex>
#include <string>
#include <vector>
using namespace std;
enum TOKENS {
OPEN_PARENTHESIS,
NEGATIVE_NUMBER,
NON_NEGATIVE_NUMBER,
CLOSE_PARENTHESIS,
ADDITION,
SUBTRACTION,
MULTIPLICATION,
DIVISION,
EQUALITY,
SIZE_TOKENS
};
int main() {
const auto input = "42/2 + -8\t=\n(2 + 2) * 2 * 2 -3"s;
vector<TOKENS> tokens;
const regex re{ "\\s*(\\(?)\\s*(-?\\s*\\d+)\\s*(\\)?)\\s*(?:(\\+)|(-)|(\\*)|(/)|(=))" };
for_each(sregex_iterator(cbegin(input), cend(input), re), sregex_iterator(), [&](const auto& i) {
if(i[1].length() > 0) {
tokens.push_back(OPEN_PARENTHESIS);
}
tokens.push_back(i[2].str().front() == '-' ? NEGATIVE_NUMBER : NON_NEGATIVE_NUMBER);
if(i[3].length() > 0) {
tokens.push_back(CLOSE_PARENTHESIS);
}
auto it = next(cbegin(i), 4);
for(int result = ADDITION; it != cend(i); ++result, ++it) {
if (it->length() > 0U) {
tokens.push_back(static_cast<TOKENS>(result));
break;
}
}
});
match_results<string::const_reverse_iterator> sm;
if(regex_search(crbegin(input), crend(input), sm, regex{ tokens.back() == SUBTRACTION ? "^\\s*\\d+\\s*-\\s*(-?)" : "^\\s*\\d+\\s*(-?)" })) {
tokens.push_back(sm[1].length() == 0 ? NON_NEGATIVE_NUMBER : NEGATIVE_NUMBER);
}
for (const auto& i : tokens) {
switch (i) {
case NEGATIVE_NUMBER:
cout << "NEGATIVE_NUMBER\n";
break;
case NON_NEGATIVE_NUMBER:
cout << "NON_NEGATIVE_NUMBER\n";
break;
case ADDITION:
cout << "ADDITION\n";
break;
case SUBTRACTION:
cout << "SUBTRACTION\n";
break;
case MULTIPLICATION:
cout << "MULTIPLICATION\n";
break;
case DIVISION:
cout << "DIVISION\n";
break;
case EQUALITY:
cout << "EQUALITY\n";
break;
case OPEN_PARENTHESIS:
cout << "OPEN_PARENTHESIS\n";
break;
case CLOSE_PARENTHESIS:
cout << "CLOSE_PARENTHESIS\n";
}
}
}
I2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8cmVnZXg+CiNpbmNsdWRlIDxzdHJpbmc+CiNpbmNsdWRlIDx2ZWN0b3I+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKZW51bSBUT0tFTlMgewogICAgT1BFTl9QQVJFTlRIRVNJUywJCiAgICBORUdBVElWRV9OVU1CRVIsCiAgICBOT05fTkVHQVRJVkVfTlVNQkVSLAogICAgQ0xPU0VfUEFSRU5USEVTSVMsCiAgICBBRERJVElPTiwKICAgIFNVQlRSQUNUSU9OLAogICAgTVVMVElQTElDQVRJT04sCiAgICBESVZJU0lPTiwKICAgIEVRVUFMSVRZLAogICAgU0laRV9UT0tFTlMKfTsKCmludCBtYWluKCkgewoJY29uc3QgYXV0byBpbnB1dCA9ICI0Mi8yICsgLThcdD1cbigyICsgMikgKiAyICogMiAtMyJzOwoJdmVjdG9yPFRPS0VOUz4gdG9rZW5zOwoJY29uc3QgcmVnZXggcmV7ICJcXHMqKFxcKD8pXFxzKigtP1xccypcXGQrKVxccyooXFwpPylcXHMqKD86KFxcKyl8KC0pfChcXCopfCgvKXwoPSkpIiB9OwoKCWZvcl9lYWNoKHNyZWdleF9pdGVyYXRvcihjYmVnaW4oaW5wdXQpLCBjZW5kKGlucHV0KSwgcmUpLCBzcmVnZXhfaXRlcmF0b3IoKSwgWyZdKGNvbnN0IGF1dG8mIGkpIHsKCQlpZihpWzFdLmxlbmd0aCgpID4gMCkgewoJCQl0b2tlbnMucHVzaF9iYWNrKE9QRU5fUEFSRU5USEVTSVMpOwoJCX0KCQkKCQl0b2tlbnMucHVzaF9iYWNrKGlbMl0uc3RyKCkuZnJvbnQoKSA9PSAnLScgPyBORUdBVElWRV9OVU1CRVIgOiBOT05fTkVHQVRJVkVfTlVNQkVSKTsKCQkKCQlpZihpWzNdLmxlbmd0aCgpID4gMCkgewoJCQl0b2tlbnMucHVzaF9iYWNrKENMT1NFX1BBUkVOVEhFU0lTKTsKCQl9CQkKCQkKCQlhdXRvIGl0ID0gbmV4dChjYmVnaW4oaSksIDQpOwoJCQoJCWZvcihpbnQgcmVzdWx0ID0gQURESVRJT047IGl0ICE9IGNlbmQoaSk7ICsrcmVzdWx0LCArK2l0KSB7CgkJCWlmIChpdC0+bGVuZ3RoKCkgPiAwVSkgewoJCQkJdG9rZW5zLnB1c2hfYmFjayhzdGF0aWNfY2FzdDxUT0tFTlM+KHJlc3VsdCkpOwoJCQkJYnJlYWs7CgkJCX0KCQl9Cgl9KTsKCQoJbWF0Y2hfcmVzdWx0czxzdHJpbmc6OmNvbnN0X3JldmVyc2VfaXRlcmF0b3I+IHNtOwoJCglpZihyZWdleF9zZWFyY2goY3JiZWdpbihpbnB1dCksIGNyZW5kKGlucHV0KSwgc20sIHJlZ2V4eyB0b2tlbnMuYmFjaygpID09IFNVQlRSQUNUSU9OID8gIl5cXHMqXFxkK1xccyotXFxzKigtPykiIDogIl5cXHMqXFxkK1xccyooLT8pIiB9KSkgewoJCXRva2Vucy5wdXNoX2JhY2soc21bMV0ubGVuZ3RoKCkgPT0gMCA/IE5PTl9ORUdBVElWRV9OVU1CRVIgOiBORUdBVElWRV9OVU1CRVIpOwoJfQoKCWZvciAoY29uc3QgYXV0byYgaSA6IHRva2VucykgewoJCXN3aXRjaCAoaSkgewoJCWNhc2UgTkVHQVRJVkVfTlVNQkVSOgoJCQljb3V0IDw8ICJORUdBVElWRV9OVU1CRVJcbiI7CgkJCWJyZWFrOwoJCWNhc2UgTk9OX05FR0FUSVZFX05VTUJFUjoKCQkJY291dCA8PCAiTk9OX05FR0FUSVZFX05VTUJFUlxuIjsKCQkJYnJlYWs7CgkJY2FzZSBBRERJVElPTjoKCQkJY291dCA8PCAiQURESVRJT05cbiI7CgkJCWJyZWFrOwoJCWNhc2UgU1VCVFJBQ1RJT046CgkJCWNvdXQgPDwgIlNVQlRSQUNUSU9OXG4iOwoJCQlicmVhazsKCQljYXNlIE1VTFRJUExJQ0FUSU9OOgoJCQljb3V0IDw8ICJNVUxUSVBMSUNBVElPTlxuIjsKCQkJYnJlYWs7CgkJY2FzZSBESVZJU0lPTjoKCQkJY291dCA8PCAiRElWSVNJT05cbiI7CgkJCWJyZWFrOwoJCWNhc2UgRVFVQUxJVFk6CgkJCWNvdXQgPDwgIkVRVUFMSVRZXG4iOwoJCQlicmVhazsKCQljYXNlIE9QRU5fUEFSRU5USEVTSVM6CgkJCWNvdXQgPDwgIk9QRU5fUEFSRU5USEVTSVNcbiI7CgkJCWJyZWFrOwoJCWNhc2UgQ0xPU0VfUEFSRU5USEVTSVM6CgkJCWNvdXQgPDwgIkNMT1NFX1BBUkVOVEhFU0lTXG4iOwoJCX0KCX0KfQ==