#include #include #include #include #include #include #include namespace HighGround { namespace Parser { enum class HGNodeType { Add, Subtract, Equal, Set, While, If, None, Root, CodeBlock }; class HGNode; class HGNode { HGNodeType nodeType = HGNodeType::None; std::vector children; public: HGNode(HGNodeType nodeType) : nodeType(nodeType) {} HGNode() = default; void addNode(HGNode in) { children.push_back(in); } std::vector generateCode() { std::vector code; return code; } }; } // namespace Parser class Lexer { std::string input; size_t size; size_t current; std::optional peek(int ahead = 1) { if (current + ahead < size) { return input[current + ahead]; } else { return {}; } } std::optional consume() { if (current < size) { return input[current++]; } else { return {}; } } public: Lexer(std::string in) : input(in), size(in.size()) {}; std::vector lex() { current = 0; std::vector tokens; std::string buf; while (auto copt = consume()) { char c = copt.value(); switch (c) { // tokens which are not followed by anything case '(': case ')': case '{': case '}': { if (!buf.empty()) { tokens.push_back(buf); buf.clear(); } tokens.push_back(std::string(1, c)); break; } // tokens which may be followed by either themselves // or an equals sign case '+': case '-': { std::string newToken(1, c); auto tokenopt = peek(); if (tokenopt) { char token = tokenopt.value(); if (token == c || token == '=') { newToken += token; consume(); } } if (!buf.empty()) { tokens.push_back(buf); buf.clear(); } tokens.push_back(newToken); break; } // tokens which may be followed by an equals sign case '*': case '/': case '=': { std::string newToken(1, c); auto tokenopt = peek(); if (tokenopt) { char token = tokenopt.value(); if (token == '=') { newToken += token; consume(); } } if (!buf.empty()) { tokens.push_back(buf); buf.clear(); } tokens.push_back(newToken); break; } // tokens which do not need to be included case ' ': case '\n': { if (!buf.empty()) { tokens.push_back(buf); buf.clear(); } break; } default: { buf += c; } } } if (!buf.empty()) { tokens.push_back(buf); } return tokens; } }; } // namespace HighGround int main(int argc, char** argv) { if (argc < 2) { std::cout << "Usage: " << argv[0] << " (file)\n"; exit(1); } std::ifstream file(argv[1]); std::ostringstream ss; ss << file.rdbuf(); auto lexed = HighGround::Lexer(ss.str()).lex(); for (const std::string& str : lexed) { std::cout << str << "\n"; } }