Push all code

This commit is contained in:
MaxanRus 2021-12-09 19:33:51 +03:00
parent 347987bb66
commit ba2bf4b404
10 changed files with 1671 additions and 0 deletions

253
src/lexer.cpp Normal file
View file

@ -0,0 +1,253 @@
#include <unordered_set>
#include <stdexcept>
#include "lexer.hpp"
bool IsNumber(char x) {
return x >= '0' && x <= '9';
}
std::unordered_set<char> special_symbols = {';', '{', '}', '(', ')', '.', ','};
bool IsSpecialSymbol(char x) {
return special_symbols.find(x) != special_symbols.end();
}
std::unordered_set<char> break_symbols = {'+', '-', '*', '/', '=', '!', '<', '>'};
bool IsBreakSymbol(char x) {
return break_symbols.find(x) != special_symbols.end();
}
void Lexer::ParseText(std::string&& text) {
using Type = LexerToken::Type;
for (char x: text) {
if (x == '\"') {
if (current_state != Type::StringLiteral) {
current_info += x;
PushToken();
current_state = Type::StringLiteral;
} else {
current_info += x;
PushToken();
}
} else if (current_state == Type::StringLiteral) {
current_info += x;
} else if (std::isspace(x)) {
PushToken();
} else if (IsBreakSymbol(x)) {
if (x == '=') {
if (current_state == Type::Plus) {
current_state = Type::PlusEqual;
PushToken();
} else if (current_state == Type::Minus) {
current_state = Type::MinusEqual;
PushToken();
} else if (current_state == Type::Star) {
current_state = Type::StarEqual;
PushToken();
} else if (current_state == Type::Slash) {
current_state = Type::SlashEqual;
PushToken();
} else if (current_state == Type::Equal) {
current_state = Type::EqualEqual;
PushToken();
} else if (current_state == Type::ExclamationMark) {
current_state = Type::ExclamationMarkEqual;
PushToken();
} else if (current_state == Type::LAngle) {
current_state = Type::LAngleEqual;
PushToken();
} else if (current_state == Type::RAngle) {
current_state = Type::RAngleEqual;
PushToken();
} else {
PushToken();
current_state = Type::Equal;
}
} else if (x == '+') {
if (current_state == Type::Plus) {
current_state = Type::PlusPlus;
PushToken();
} else {
PushToken();
current_state = Type::Plus;
}
} else if (x == '-') {
if (current_state == Type::Minus) {
current_state = Type::MinusMinus;
PushToken();
} else if (current_state == Type::LAngle) {
current_state = Type::LArrow;
PushToken();
} else {
PushToken();
current_state = Type::Minus;
}
} else if (x == '>') {
if (current_state == Type::Minus) {
current_state = Type::RArrow;
PushToken();
} else {
PushToken();
current_state = Type::RAngle;
}
} else {
PushToken();
if (x == '+') {
current_state = Type::Plus;
} else if (x == '-') {
current_state = Type::Minus;
} else if (x == '*') {
current_state = Type::Star;
} else if (x == '/') {
current_state = Type::Slash;
} else if (x == '=') {
current_state = Type::Equal;
} else if (x == '!') {
current_state = Type::ExclamationMark;
} else if (x == '<') {
current_state = Type::LAngle;
} else if (x == '>') {
current_state = Type::RAngle;
} else {
throw std::logic_error("incorrect operator");
}
}
} else if (current_state == Type::None || IsSpecialSymbol(x)) {
PushToken();
if (x == ';') {
current_state = Type::Semicolon;
PushToken();
} else if (x == '{') {
current_state = Type::CurlyOpenBracket;
PushToken();
} else if (x == '}') {
current_state = Type::CurlyCloseBracket;
PushToken();
} else if (x == '(') {
current_state = Type::RoundOpenBracket;
PushToken();
} else if (x == ')') {
current_state = Type::RoundCloseBracket;
PushToken();
} else if (x == '.') {
current_state = Type::Period;
PushToken();
} else if (x == ',') {
current_state = Type::Commo;
PushToken();
} else {
current_state = Type::Word;
current_info += x;
}
} else if (current_state == Type::Word) {
current_info += x;
}
}
PushToken();
}
void Lexer::ParseText(const std::string& text) {
std::string copy(text);
ParseText(std::move(copy));
}
void Lexer::PushToken() {
using Type = LexerToken::Type;
if (current_state != Type::None) {
if (current_state == Type::Word && current_info == "for") {
current_state = Type::FOR;
current_info.clear();
} else if (current_state == Type::Word && current_info == "while") {
current_state = Type::WHILE;
current_info.clear();
} else if (current_state == Type::Word && current_info == "if") {
current_state = Type::IF;
current_info.clear();
} else if (current_state == Type::Word && current_info == "else") {
current_state = Type::ELSE;
current_info.clear();
}
tokens.emplace_back(current_state, std::move(current_info));
current_state = Type::None;
current_info.clear();
}
}
LexerTokenList Lexer::GetTokens() const {
return tokens;
}
namespace std {
std::string to_string(Lexer::LexerToken::Type x) {
using Type = Lexer::LexerToken::Type;
if (x == Type::None) {
return "None";
} else if (x == Type::Word) {
return "Word";
} else if (x == Type::Semicolon) {
return "Semicolon";
} else if (x == Type::CurlyOpenBracket) {
return "CurlyOpenBrackets";
} else if (x == Type::CurlyCloseBracket) {
return "CurlyCloseBrackets";
} else if (x == Type::RoundOpenBracket) {
return "RoundOpenBrackets";
} else if (x == Type::RoundCloseBracket) {
return "RoundCloseBrackets";
} else if (x == Type::Commo) {
return "Commo";
} else if (x == Type::Plus) {
return "Plus";
} else if (x == Type::Minus) {
return "Minus";
} else if (x == Type::Star) {
return "Star";
} else if (x == Type::Slash) {
return "Slash";
} else if (x == Type::Equal) {
return "Equal";
} else if (x == Type::ExclamationMark) {
return "ExclamationMark";
} else if (x == Type::PlusEqual) {
return "PlusEqual";
} else if (x == Type::MinusEqual) {
return "MinusEqual";
} else if (x == Type::StarEqual) {
return "StarEqual";
} else if (x == Type::SlashEqual) {
return "SlashEqual";
} else if (x == Type::EqualEqual) {
return "EqualEqual";
} else if (x == Type::ExclamationMarkEqual) {
return "ExclamationMarkEqual";
} else if (x == Type::PlusPlus) {
return "PlusPlus";
} else if (x == Type::MinusMinus) {
return "MinusMinus";
} else if (x == Type::LAngle) {
return "LAngle";
} else if (x == Type::RAngle) {
return "RAngle";
} else if (x == Type::LAngleEqual) {
return "LAngleEqual";
} else if (x == Type::RAngleEqual) {
return "RAngleEqual";
} else if (x == Type::LArrow) {
return "LArrow";
} else if (x == Type::RArrow) {
return "RArrow";
} else if (x == Type::FOR) {
return "for";
} else if (x == Type::WHILE) {
return "while";
} else if (x == Type::IF) {
return "if";
} else if (x == Type::ELSE) {
return "else";
} else {
return "ERROR";
}
}
}