2022-10-17 22:26:36 -03:00
|
|
|
#ifndef OBELISK_LEXER_H
|
|
|
|
#define OBELISK_LEXER_H
|
|
|
|
|
2023-02-13 23:03:31 -03:00
|
|
|
#include <fstream>
|
2022-10-17 22:26:36 -03:00
|
|
|
#include <string>
|
|
|
|
|
|
|
|
namespace obelisk
|
|
|
|
{
|
2022-12-09 23:41:54 -03:00
|
|
|
/**
|
2022-12-09 23:54:55 -03:00
|
|
|
* @brief The Lexer reads and identifies tokens in the obelisk source code.
|
2022-12-09 23:41:54 -03:00
|
|
|
*
|
|
|
|
*/
|
2022-10-17 22:26:36 -03:00
|
|
|
class Lexer
|
|
|
|
{
|
|
|
|
private:
|
2023-02-13 23:03:31 -03:00
|
|
|
int lastChar = ' ';
|
|
|
|
/**
|
|
|
|
* @brief The stream of the source file being read.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
std::ifstream fileStream_;
|
2022-12-09 23:41:54 -03:00
|
|
|
/**
|
|
|
|
* @brief The last found identifier.
|
|
|
|
*
|
|
|
|
*/
|
2022-10-17 22:26:36 -03:00
|
|
|
std::string identifier_;
|
2022-12-09 23:41:54 -03:00
|
|
|
/**
|
|
|
|
* @brief The last found number.
|
|
|
|
*
|
|
|
|
*/
|
2023-02-13 23:03:31 -03:00
|
|
|
double numberValue_ = 0;
|
2022-10-17 22:26:36 -03:00
|
|
|
|
2022-12-09 23:41:54 -03:00
|
|
|
/**
|
|
|
|
* @brief Set the identifier.
|
|
|
|
*
|
|
|
|
* @param[in] identifier The new identifier.
|
|
|
|
*/
|
2022-11-04 11:19:30 -03:00
|
|
|
void setIdentifier(const std::string& identifier);
|
2022-12-09 23:41:54 -03:00
|
|
|
/**
|
|
|
|
* @brief Erase the last identifier.
|
|
|
|
*
|
|
|
|
*/
|
2022-10-17 22:26:36 -03:00
|
|
|
void eraseIdentifier();
|
2022-12-09 23:41:54 -03:00
|
|
|
/**
|
|
|
|
* @brief Add the last found char to the end of the identifier.
|
|
|
|
*
|
|
|
|
* @param[in] lastChar The last char that was found.
|
|
|
|
*/
|
2022-10-17 22:26:36 -03:00
|
|
|
void appendIdentifier(int lastChar);
|
2022-12-09 23:41:54 -03:00
|
|
|
/**
|
|
|
|
* @brief Set the number value.
|
|
|
|
*
|
|
|
|
* @param[in] numberValue The new number value.
|
|
|
|
*/
|
2022-10-17 22:26:36 -03:00
|
|
|
void setNumberValue(double numberValue);
|
2022-12-09 23:41:54 -03:00
|
|
|
/**
|
|
|
|
* @brief Comment the rest of the line.
|
|
|
|
*
|
2022-12-10 17:40:30 -03:00
|
|
|
* @param[in] lastChar The char to check to see if it in the end of
|
|
|
|
* the line.
|
2022-12-09 23:41:54 -03:00
|
|
|
*/
|
2022-10-17 22:26:36 -03:00
|
|
|
void commentLine(int* lastChar);
|
|
|
|
|
|
|
|
public:
|
2022-12-09 23:41:54 -03:00
|
|
|
/**
|
2022-12-10 17:40:30 -03:00
|
|
|
* @brief These token represent recognized language keywords and
|
|
|
|
* language functionality.
|
2022-12-09 23:41:54 -03:00
|
|
|
*
|
|
|
|
*/
|
2022-10-17 22:26:36 -03:00
|
|
|
enum Token
|
|
|
|
{
|
2022-12-09 23:41:54 -03:00
|
|
|
/**
|
2022-12-10 17:40:30 -03:00
|
|
|
* @brief End of file is returned when the source code is
|
|
|
|
* finished.
|
2022-12-09 23:41:54 -03:00
|
|
|
*
|
|
|
|
*/
|
2022-11-04 11:19:30 -03:00
|
|
|
kTokenEof = -1,
|
2022-10-17 22:26:36 -03:00
|
|
|
|
2022-12-09 23:41:54 -03:00
|
|
|
/**
|
|
|
|
* @brief A fact which is a relationship between 2 entities.
|
|
|
|
*
|
|
|
|
*/
|
2022-11-04 11:19:30 -03:00
|
|
|
kTokenFact = -2,
|
2022-12-09 23:41:54 -03:00
|
|
|
/**
|
2022-12-10 17:40:30 -03:00
|
|
|
* @brief A rule which is a relationship between a new fact a
|
|
|
|
* existing fact.
|
2022-12-09 23:41:54 -03:00
|
|
|
*
|
|
|
|
*/
|
2022-11-04 11:19:30 -03:00
|
|
|
kTokenRule = -3,
|
2022-12-09 23:41:54 -03:00
|
|
|
/**
|
|
|
|
* @brief An action to take if a fact is true.
|
|
|
|
*
|
|
|
|
*/
|
2022-11-04 11:19:30 -03:00
|
|
|
kTokenAction = -4,
|
2022-12-09 23:41:54 -03:00
|
|
|
/**
|
|
|
|
* @brief A definition of a new function.
|
|
|
|
*
|
|
|
|
*/
|
2022-10-17 22:26:36 -03:00
|
|
|
kTokenDef = -5,
|
2022-12-09 23:41:54 -03:00
|
|
|
/**
|
|
|
|
* @brief An external function that will be linked to.
|
|
|
|
*
|
|
|
|
*/
|
2022-10-17 22:26:36 -03:00
|
|
|
kTokenExtern = -6,
|
|
|
|
|
2022-12-09 23:41:54 -03:00
|
|
|
/**
|
|
|
|
* @brief An identifier which is a alphanumeric value.
|
|
|
|
*
|
|
|
|
*/
|
2022-10-17 22:26:36 -03:00
|
|
|
kTokenIdentifier = -7,
|
2022-12-09 23:41:54 -03:00
|
|
|
/**
|
|
|
|
* @brief A double floating point value.
|
|
|
|
*
|
|
|
|
*/
|
2022-10-17 22:26:36 -03:00
|
|
|
kTokenNumber = -8,
|
2022-12-09 23:41:54 -03:00
|
|
|
/**
|
|
|
|
* @brief A string.
|
|
|
|
*
|
|
|
|
*/
|
2022-10-17 22:26:36 -03:00
|
|
|
kTokenString = -9
|
|
|
|
};
|
|
|
|
|
2023-02-13 23:03:31 -03:00
|
|
|
/**
|
|
|
|
* @brief Construct a new Lexer object.
|
|
|
|
*
|
|
|
|
* @param[in] sourceFile The source file to read.
|
|
|
|
*/
|
|
|
|
Lexer(const std::string& sourceFile);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Destroy the Lexer object.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
~Lexer();
|
|
|
|
|
2022-12-09 23:41:54 -03:00
|
|
|
/**
|
|
|
|
* @brief Gets the next token in the source code.
|
|
|
|
*
|
2022-12-10 00:28:24 -03:00
|
|
|
* @throws LexerException when an invalid token is found.
|
2022-12-10 17:40:30 -03:00
|
|
|
* @return int Returns a Token value or char if no known token was
|
|
|
|
* found.
|
2022-12-09 23:41:54 -03:00
|
|
|
*/
|
2022-10-17 22:26:36 -03:00
|
|
|
int getToken();
|
|
|
|
|
2022-12-09 23:41:54 -03:00
|
|
|
/**
|
|
|
|
* @brief Get the last identifier.
|
|
|
|
*
|
2022-12-10 17:40:30 -03:00
|
|
|
* @return const std::string& Returns a string that contains the
|
|
|
|
* last found identifier.
|
2022-12-09 23:41:54 -03:00
|
|
|
*/
|
2022-11-04 11:19:30 -03:00
|
|
|
const std::string& getIdentifier();
|
2022-12-09 23:41:54 -03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Get the last number value.
|
|
|
|
*
|
|
|
|
* @return double Return the last number that was found.
|
|
|
|
*/
|
2022-10-17 22:26:36 -03:00
|
|
|
double getNumberValue();
|
|
|
|
};
|
2022-11-30 22:44:08 -03:00
|
|
|
|
2022-12-09 23:41:54 -03:00
|
|
|
/**
|
|
|
|
* @brief Lexer exception class.
|
|
|
|
*
|
|
|
|
*/
|
2022-11-30 22:44:08 -03:00
|
|
|
class LexerException : public std::exception
|
|
|
|
{
|
|
|
|
private:
|
2022-12-09 23:41:54 -03:00
|
|
|
/**
|
|
|
|
* @brief The error message from the exception.
|
|
|
|
*
|
|
|
|
*/
|
2022-11-30 22:44:08 -03:00
|
|
|
const std::string errorMessage_;
|
|
|
|
|
|
|
|
public:
|
2022-12-09 23:41:54 -03:00
|
|
|
/**
|
2022-12-10 18:23:04 -03:00
|
|
|
* @brief Construct a new LexerException object.
|
2022-12-09 23:41:54 -03:00
|
|
|
*
|
|
|
|
*/
|
2022-11-30 22:44:08 -03:00
|
|
|
LexerException() :
|
|
|
|
errorMessage_("an unknown error ocurred")
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2022-12-09 23:41:54 -03:00
|
|
|
/**
|
2022-12-10 18:23:04 -03:00
|
|
|
* @brief Construct a new LexerException object.
|
2022-12-09 23:41:54 -03:00
|
|
|
*
|
2022-12-10 17:31:39 -03:00
|
|
|
* @param[in] errorMessage Error message to include.
|
2022-12-09 23:41:54 -03:00
|
|
|
*/
|
2022-11-30 22:44:08 -03:00
|
|
|
LexerException(const std::string& errorMessage) :
|
|
|
|
errorMessage_(errorMessage)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2022-12-09 23:41:54 -03:00
|
|
|
/**
|
|
|
|
* @brief Return the exception's error message.
|
|
|
|
*
|
2022-12-10 17:40:30 -03:00
|
|
|
* @return const char* Returns a string containing the error
|
|
|
|
* message.
|
2022-12-09 23:41:54 -03:00
|
|
|
*/
|
2022-11-30 22:44:08 -03:00
|
|
|
const char* what() const noexcept
|
|
|
|
{
|
|
|
|
return errorMessage_.c_str();
|
|
|
|
}
|
|
|
|
};
|
2022-10-17 22:26:36 -03:00
|
|
|
} // namespace obelisk
|
|
|
|
|
|
|
|
#endif
|