obelisk/src/lexer.cpp

160 lines
3.0 KiB
C++
Raw Permalink Normal View History

2022-10-17 22:26:36 -03:00
#include "lexer.h"
#include <iostream>
obelisk::Lexer::Lexer(const std::string& sourceFile)
2022-10-17 22:26:36 -03:00
{
fileStream_.open(sourceFile, std::ifstream::in);
if (!fileStream_)
{
throw obelisk::LexerException(
"could not open source file " + sourceFile);
}
}
2022-10-17 22:26:36 -03:00
obelisk::Lexer::~Lexer()
{
fileStream_.close();
fileStream_.clear();
}
int obelisk::Lexer::getToken()
{
2022-10-17 22:26:36 -03:00
while (isspace(lastChar))
{
lastChar = fileStream_.get();
2022-10-17 22:26:36 -03:00
}
if (isalpha(lastChar))
{
eraseIdentifier();
appendIdentifier(lastChar);
while (isalnum((lastChar = fileStream_.get())))
2022-10-17 22:26:36 -03:00
{
appendIdentifier(lastChar);
}
if (getIdentifier() == "fact")
{
return Token::kTokenFact;
}
if (getIdentifier() == "rule")
{
2023-02-18 23:02:49 -03:00
return Token::kTokenRule;
}
if (getIdentifier() == "action")
{
return Token::kTokenAction;
}
2022-10-17 22:26:36 -03:00
if (getIdentifier() == "def")
{
return Token::kTokenDef;
}
if (getIdentifier() == "extern")
{
2023-02-28 22:11:48 -03:00
return Token::kTokenExtern;
2022-10-17 22:26:36 -03:00
}
2023-02-28 22:11:48 -03:00
return Token::kTokenIdentifier;
2022-10-17 22:26:36 -03:00
}
if (isdigit(lastChar))
2022-10-17 22:26:36 -03:00
{
bool firstPeriod = false;
2022-10-17 22:26:36 -03:00
std::string numberStr;
do
{
if (firstPeriod && lastChar == '.')
{
throw obelisk::LexerException("invalid double value");
}
else if (!firstPeriod && lastChar == '.')
{
firstPeriod = true;
}
2022-10-17 22:26:36 -03:00
numberStr += lastChar;
lastChar = fileStream_.get();
2022-10-17 22:26:36 -03:00
}
while (isdigit(lastChar) || lastChar == '.');
setNumberValue(strtod(numberStr.c_str(), nullptr));
return kTokenNumber;
}
if (lastChar == '#')
{
commentLine(&lastChar);
if (lastChar != EOF)
{
return getToken();
}
}
else if (lastChar == '/')
{
lastChar = fileStream_.get();
2022-10-17 22:26:36 -03:00
if (lastChar == '/')
{
commentLine(&lastChar);
if (lastChar != EOF)
{
return getToken();
}
}
}
if (lastChar == EOF)
{
return kTokenEof;
}
int thisChar = lastChar;
lastChar = fileStream_.get();
2022-10-17 22:26:36 -03:00
return thisChar;
}
void obelisk::Lexer::commentLine(int* lastChar)
{
do
{
*lastChar = fileStream_.get();
2022-10-17 22:26:36 -03:00
}
while (*lastChar != EOF && *lastChar != '\n' && *lastChar != '\r');
}
const std::string& obelisk::Lexer::getIdentifier()
2022-10-17 22:26:36 -03:00
{
return identifier_;
}
void obelisk::Lexer::setIdentifier(const std::string& identifier)
2022-10-17 22:26:36 -03:00
{
identifier_ = identifier;
}
void obelisk::Lexer::eraseIdentifier()
{
identifier_ = "";
}
void obelisk::Lexer::appendIdentifier(int lastChar)
{
identifier_ += lastChar;
}
double obelisk::Lexer::getNumberValue()
{
return numberValue_;
}
void obelisk::Lexer::setNumberValue(double numberValue)
{
numberValue_ = numberValue;
}