122 lines
2.6 KiB
C++
122 lines
2.6 KiB
C++
#include "Lexer.h"
|
|
#include <iostream>
|
|
|
|
namespace Parser
|
|
{
|
|
using Parser::Lexer;
|
|
std::list<Lexer::Token> Lexer::tokenize(const std::string_view &text)
|
|
{
|
|
tokens.clear();
|
|
this->text = text;
|
|
|
|
while (current != text.length())
|
|
{
|
|
if (text.at(current) == ' ')
|
|
{
|
|
advance();
|
|
continue;
|
|
}
|
|
if (text.at(current) == '\n')
|
|
{
|
|
advance();
|
|
line++;
|
|
continue;
|
|
}
|
|
|
|
start = current;
|
|
|
|
switch (Lexer::peek())
|
|
{
|
|
case '+':
|
|
advance();
|
|
token(Token::PLUS);
|
|
break;
|
|
case '-':
|
|
advance();
|
|
token(Token::MINUS);
|
|
break;
|
|
case '*':
|
|
advance();
|
|
token(Token::MULTIPLY);
|
|
break;
|
|
case '/':
|
|
advance();
|
|
token(Token::DIVIDE);
|
|
break;
|
|
case '=':
|
|
advance();
|
|
token(Token::ASSIGNMENT);
|
|
break;
|
|
case '(':
|
|
advance();
|
|
token(Token::BRACKET_LEFT);
|
|
break;
|
|
case ')':
|
|
advance();
|
|
token(Token::BRACKET_RIGHT);
|
|
break;
|
|
|
|
default:
|
|
if (isDigit(peek()))
|
|
{
|
|
advance();
|
|
number();
|
|
}
|
|
|
|
if (isAlpha(peek()))
|
|
{
|
|
advance();
|
|
identifier();
|
|
}
|
|
}
|
|
}
|
|
|
|
return tokens;
|
|
}
|
|
void Lexer::advance()
|
|
{
|
|
current++;
|
|
}
|
|
|
|
char Lexer::peek()
|
|
{
|
|
if (current == text.length())
|
|
return 0;
|
|
return text.at(current);
|
|
}
|
|
|
|
void Lexer::token(const Token::TokenType type)
|
|
{
|
|
tokens.emplace_back(Token(type, line, text.substr(start, (current - start))));
|
|
}
|
|
|
|
bool Lexer::isDigit(const char &c)
|
|
{
|
|
return c >= '0' && c <= '9';
|
|
}
|
|
|
|
void Lexer::number()
|
|
{
|
|
while (isDigit(peek()))
|
|
{
|
|
advance();
|
|
}
|
|
|
|
token(Token::INT);
|
|
}
|
|
|
|
bool Lexer::isAlpha(const char &c)
|
|
{
|
|
return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'));
|
|
}
|
|
|
|
void Lexer::identifier()
|
|
{
|
|
while (isAlpha(peek()) || isDigit(peek()))
|
|
{
|
|
advance();
|
|
}
|
|
|
|
token(Token::IDENTIFIER);
|
|
}
|
|
} |