2024-02-22 21:29:25 +01:00
|
|
|
#include "elna/lexer.hpp"
|
|
|
|
|
|
|
|
namespace elna
|
|
|
|
{
|
|
|
|
source::source(const std::string& buffer)
|
|
|
|
: m_buffer(buffer)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
source::const_iterator source::begin() const
|
|
|
|
{
|
2024-02-25 15:16:19 +01:00
|
|
|
return source::const_iterator(std::cbegin(m_buffer));
|
2024-02-22 21:29:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
source::const_iterator source::end() const
|
|
|
|
{
|
2024-02-25 15:16:19 +01:00
|
|
|
source_position end_position{ 0, 0 };
|
2024-02-22 21:29:25 +01:00
|
|
|
|
|
|
|
return source::const_iterator(std::cend(m_buffer), end_position);
|
|
|
|
}
|
|
|
|
|
2024-02-25 15:16:19 +01:00
|
|
|
source::const_iterator::const_iterator(std::string::const_iterator buffer,
|
|
|
|
const source_position start_position)
|
2024-02-22 21:29:25 +01:00
|
|
|
: m_buffer(buffer), m_position(start_position)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2024-02-25 15:16:19 +01:00
|
|
|
const source_position& source::const_iterator::position() const noexcept
|
2024-02-22 21:29:25 +01:00
|
|
|
{
|
|
|
|
return this->m_position;
|
|
|
|
}
|
|
|
|
|
|
|
|
source::const_iterator::reference source::const_iterator::operator*() const noexcept
|
|
|
|
{
|
|
|
|
return *m_buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
source::const_iterator::pointer source::const_iterator::operator->() const noexcept
|
|
|
|
{
|
|
|
|
return m_buffer.base();
|
|
|
|
}
|
|
|
|
|
|
|
|
source::const_iterator& source::const_iterator::operator++()
|
|
|
|
{
|
|
|
|
if (*this->m_buffer == '\n')
|
|
|
|
{
|
|
|
|
this->m_position.column = 1;
|
|
|
|
++this->m_position.line;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
++this->m_position.column;
|
|
|
|
}
|
|
|
|
std::advance(this->m_buffer, 1);
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
source::const_iterator& source::const_iterator::operator++(int)
|
|
|
|
{
|
|
|
|
auto tmp = *this;
|
|
|
|
++(*this);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool source::const_iterator::operator==(const source::const_iterator& that) const noexcept
|
|
|
|
{
|
|
|
|
return this->m_buffer == that.m_buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool source::const_iterator::operator!=(const source::const_iterator& that) const noexcept
|
|
|
|
{
|
|
|
|
return !(*this == that);
|
|
|
|
}
|
|
|
|
|
|
|
|
token::token(const type of, source::const_iterator begin, source::const_iterator end)
|
|
|
|
: m_type(of), m_value(begin, end)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
token::type token::of() const noexcept
|
|
|
|
{
|
|
|
|
return m_type;
|
|
|
|
}
|
|
|
|
|
|
|
|
const token::value& token::identifier() const noexcept
|
|
|
|
{
|
|
|
|
return m_value;
|
|
|
|
}
|
|
|
|
|
2024-02-25 15:16:19 +01:00
|
|
|
const source_position& token::position() const noexcept
|
2024-02-22 21:29:25 +01:00
|
|
|
{
|
|
|
|
return m_position;
|
|
|
|
}
|
|
|
|
|
|
|
|
result<std::vector<token>> lex(const std::string& buffer)
|
|
|
|
{
|
|
|
|
std::vector<token> tokens;
|
|
|
|
source input{ buffer };
|
|
|
|
|
|
|
|
for (auto iterator = input.begin(); iterator != input.end();)
|
|
|
|
{
|
|
|
|
if (*iterator == ' ' || *iterator == '\n')
|
|
|
|
{
|
|
|
|
}
|
|
|
|
else if (std::isgraph(*iterator))
|
|
|
|
{
|
|
|
|
auto current_position = iterator;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
++current_position;
|
|
|
|
}
|
|
|
|
while (current_position != input.end() && std::isgraph(*current_position));
|
|
|
|
token new_token{ token::type::word, iterator, current_position };
|
|
|
|
|
|
|
|
tokens.push_back(new_token);
|
|
|
|
iterator = current_position;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
++iterator;
|
|
|
|
}
|
|
|
|
|
|
|
|
return tokens;
|
|
|
|
}
|
|
|
|
}
|