Yerbacon/src/etc/lexer.cpp

66 lines
2.8 KiB
C++

#include "../headers/lex.hpp"
using namespace std;
tok::type getIdentifierCharType(const char& Char) {
if (isalpha(Char)) return tok::IDENTIFIER;
else if (isdigit(Char)) return tok::NUMBER;
else if (Char == '"') return tok::STRING;
else return tok::UNEXPECTED;
}
vector<tok> lex(const string& in)
{
vector<tok> resVal;
for (unsigned int i = 0; i < in.size(); ++i) {
const char& current = in[i];
switch (current) {
case '#': resVal.emplace_back(tok::TAG, "#"); break;
case '=': resVal.emplace_back(tok::DEFINE, "="); break;
case '(': resVal.emplace_back(tok::LPAR, "("); break;
case ')': resVal.emplace_back(tok::RPAR, ")"); break;
case '{': resVal.emplace_back(tok::LBRACE, "{"); break;
case '}': resVal.emplace_back(tok::RBRACE, "}"); break;
case '[': resVal.emplace_back(tok::LBRACKET, "["); break;
case ']': resVal.emplace_back(tok::RBRACKET, "]"); break;
case '+': resVal.emplace_back(tok::PLUS, "+"); break;
case '-': resVal.emplace_back(tok::HYPHEN, "-"); break;
case '>': resVal.emplace_back(tok::LCOMP, ">"); break;
case '<': resVal.emplace_back(tok::RCOMP, "<"); break;
case '\'': resVal.emplace_back(tok::SQUOTE, "\'"); break;
case ' ': case '\t': case '\r':
case '\n': break;
default: {
tok::type type = getIdentifierCharType(current);
bool isTypeString = (type == tok::STRING);
switch (type) {
case tok::UNEXPECTED: break;
case tok::STRING: ++i;
case tok::IDENTIFIER: case tok::NUMBER: {
string formedString;
for (;i < in.size(); ++i) {
tok::type currentCharType = getIdentifierCharType(in[i]);
bool isString = currentCharType == tok::STRING;
if (i == in.size() - 1 && not isString) throw tok::LexerException("A never ending string was found");
if ((currentCharType == type || isTypeString) && !isString) {
formedString += string(1, in[i]);
} else {
if (not isTypeString) --i;
resVal.emplace_back(type, formedString);
break;
}
}
break;
}
default: resVal.emplace_back(type, string(1, current));
}
break;
}
}
}
/* Test
for (const auto& it : resVal) {
cout << it.toktext << ' ' << it.toktype << '\n';
}
*/
return resVal;
}