-
인터프리터...14일지 2020. 11. 12. 22:05
토큰 처리
Tokenizer.h
#pragma region 키워드표 struct Keyword { const char* str; TokenKind type; }; Keyword keywordList[] = { {"if", TokenKind::If}, {"else", TokenKind::Else}, {"end", TokenKind::End}, {"print", TokenKind::Print}, {"(", TokenKind::LeftParenthesis}, {")", TokenKind::RightParenthesis}, {"==", TokenKind::Equal}, {"!=", TokenKind::NotEqual}, {"<", TokenKind::Less}, {">", TokenKind::Grater}, {"<=", TokenKind::LessEqual}, {">=", TokenKind::GraterEqual}, {"+", TokenKind::Plus}, {"-", TokenKind::Minus}, {"*", TokenKind::Multiply}, {"/", TokenKind::Divide}, {"=", TokenKind::Assign}, }; TokenKind GetKind(const string& str) { for (const Keyword& keyword : keywordList) { if (str == keyword.str) { return keyword.type; } } if (charType[str[0]] == TokenKind::Letter) { return TokenKind::Identifier; } return TokenKind::Others; } #pragma endregion #pragma region 토큰 처리 string emptyString{ "" }; int ch{ ' ' }; int NextCharacter() { if (ifs.is_open()) { if (ifs.eof()) { ifs.close(); } else { return ifs.get(); } } return EOF; } bool IsSize2Operator(const int ch1, const int ch2) { static string size2Operator{ ">= <= == !=" }; if (ch1 == '\0' || ch2 == '\0') { return false; } string op(sizeof(ch1), ch1); op.append(sizeof(ch2), ch2); return size2Operator.find(op) != string::npos; } Token NextToken() { if (ch == EOF) { return Token(TokenKind::EndOfToken, emptyString); } // 공백 스킵 while (isspace(ch)) { ch = NextCharacter(); }; string str{ emptyString }; int num{ 0 }; switch (charType[ch]) { case TokenKind::Digit: do { num = num * 10 + (ch - '0'); ch = NextCharacter(); } while (charType[ch] == TokenKind::Digit); return Token(TokenKind::Int, str, num); case TokenKind::DoubleQuotes: ch = NextCharacter(); while (charType[ch] != TokenKind::DoubleQuotes) { str.append(sizeof(ch), ch); ch = NextCharacter(); if (ch == EOF) { std::cout << "\"의 짝이 맞지 않습니다."; exit(1); } } ch = NextCharacter(); return Token(TokenKind::String, str); case TokenKind::Letter: do { str.append(sizeof(ch), ch); ch = NextCharacter(); } while (charType[ch] == TokenKind::Letter); break; default: str.append(sizeof(ch), ch); ch = NextCharacter(); if (IsSize2Operator(*str.c_str(), ch)) { str.append(sizeof(ch), ch); ch = NextCharacter(); } break; } TokenKind tokenKind{ GetKind(str) }; if (tokenKind == TokenKind::Others) { std::cout << "지원하지 않는 문자입니다."; exit(1); } return Token(tokenKind, str); } #pragma endregion
더보기참고문헌