stela/parser.hpp

143 lines
2.5 KiB
C++
Raw Permalink Normal View History

2024-07-19 00:46:30 +01:00
#pragma once
#include <cstdint>
#include <fstream>
#include <string>
#include <unordered_map>
#include <vector>
namespace stela {
struct Pos {
size_t index;
int64_t line;
int64_t col;
};
struct Error {
Pos pos;
std::string message;
};
enum class TokenType {
Error,
Eof,
If,
Else,
Return,
Public,
Private,
Class,
Derivable,
Derives,
Enumeration,
Associate,
Attribute,
Operation,
StateMachine,
Transition,
Initial,
Final,
Entry,
Exit,
LParen,
RParen,
LBrace,
RBrace,
LBracket,
RBracket,
Dot,
Comma,
Semicolon,
Colon,
ColonColon,
Minus,
MinusLt,
Equal,
Id,
Int,
};
struct Token {
TokenType type;
Pos pos;
uint64_t id;
};
class Lexer {
public:
Lexer(std::ifstream& file, std::vector<Error>& errors)
: file(&file)
, current_char(file.get())
, errors(&errors)
{ }
auto next() -> Token;
private:
inline auto step()
{
if (this->current_char == EOF) {
this->eof_reached = true;
return;
}
if (this->current_char == '\n') {
this->line += 1;
this->col = 1;
} else {
this->col += 1;
}
this->current_char = this->file->get();
this->index += 1;
}
inline auto single_token(TokenType type, Pos pos) -> Token
{
step();
return token(type, pos);
}
inline auto error_token(Pos pos, std::string message) const -> Token
{
this->errors->push_back(Error { pos, message });
return token(TokenType::Error, pos);
}
inline auto token(TokenType type, Pos pos) const -> Token
{
return Token { type, pos, 0 };
}
inline auto pos() const -> Pos
{
return Pos {
.index = this->index,
.line = this->line,
.col = this->col,
};
}
inline auto done() const -> bool { return this->eof_reached; }
inline auto current() const -> char
{
return static_cast<char>(this->current_char);
}
auto populate_keyword_map();
bool eof_reached = false;
size_t index = 0;
int64_t line = 1;
int64_t col = 1;
std::ifstream* file;
int current_char;
std::unordered_map<std::string, TokenType> keyword_map {};
std::vector<std::string> symbol_values {};
std::vector<int64_t> int_values {};
std::vector<Error>* errors;
};
}