elna/include/elna/lexer.hpp

86 lines
2.0 KiB
C++

#pragma once
#include <string>
#include "elna/result.hpp"
namespace elna
{
/**
* Range over the source text that keeps track of the current position.
*/
struct source
{
class const_iterator
{
std::string::const_iterator m_buffer;
Position m_position;
const_iterator(std::string::const_iterator buffer, const Position& position);
public:
using iterator_category = std::forward_iterator_tag;
using difference_type = ptrdiff_t;
using value_type = char;
using pointer = const value_type *;
using reference = const value_type&;
const Position& position() const noexcept;
reference operator*() const noexcept;
pointer operator->() const noexcept;
const_iterator& operator++();
const_iterator& operator++(int);
bool operator==(const const_iterator& that) const noexcept;
bool operator!=(const const_iterator& that) const noexcept;
friend source;
};
source(const std::string& buffer);
const_iterator begin() const;
const_iterator end() const;
private:
const std::string& m_buffer;
};
/**
* Union type representing a single token.
*/
struct token
{
/**
* Token type.
*/
enum class type
{
word,
};
/**
* Type of the token value.
*/
using value = std::string;
token(const type of, source::const_iterator begin, source::const_iterator end);
type of() const noexcept;
const value& identifier() const noexcept;
const Position& position() const noexcept;
private:
std::string m_value;
Position m_position;
type m_type;
};
/**
* Split the source into tokens.
*
* \return Tokens or error.
*/
result<std::vector<token>> lex(const std::string& buffer);
}