feature/error_handling #9

Merged
cromer merged 2 commits from feature/error_handling into develop 2022-12-08 20:07:36 -03:00
4 changed files with 85 additions and 12 deletions

View File

@ -48,11 +48,20 @@ int obelisk::Lexer::getToken()
return kTokenIdentifier; return kTokenIdentifier;
} }
if (isdigit(lastChar) || lastChar == '.') if (isdigit(lastChar))
{ {
bool firstPeriod = false;
std::string numberStr; std::string numberStr;
do do
{ {
if (firstPeriod && lastChar == '.')
{
throw obelisk::LexerException("invalid double value");
}
else if (!firstPeriod && lastChar == '.')
{
firstPeriod = true;
}
numberStr += lastChar; numberStr += lastChar;
lastChar = getchar(); lastChar = getchar();
} }

View File

@ -3,7 +3,6 @@
#include <string> #include <string>
// TODO: add error handling
namespace obelisk namespace obelisk
{ {
class Lexer class Lexer
@ -41,6 +40,28 @@ namespace obelisk
const std::string& getIdentifier(); const std::string& getIdentifier();
double getNumberValue(); double getNumberValue();
}; };
class LexerException : public std::exception
{
private:
const std::string errorMessage_;
public:
LexerException() :
errorMessage_("an unknown error ocurred")
{
}
LexerException(const std::string& errorMessage) :
errorMessage_(errorMessage)
{
}
const char* what() const noexcept
{
return errorMessage_.c_str();
}
};
} // namespace obelisk } // namespace obelisk
#endif #endif

View File

@ -26,7 +26,15 @@ static int mainLoop()
// Prime the first token. // Prime the first token.
fprintf(stderr, "ready> "); fprintf(stderr, "ready> ");
parser->getNextToken(); try
{
parser->getNextToken();
}
catch (obelisk::LexerException& exception)
{
std::cout << "Error: " << exception.what() << std::endl;
return EXIT_FAILURE;
}
while (true) while (true)
{ {
@ -40,7 +48,15 @@ static int mainLoop()
<< parser->getLexer()->getIdentifier() << std::endl; << parser->getLexer()->getIdentifier() << std::endl;
std::cout << "Num: " << parser->getLexer()->getNumberValue() std::cout << "Num: " << parser->getLexer()->getNumberValue()
<< std::endl; << std::endl;
parser->getNextToken(); try
{
parser->getNextToken();
}
catch (obelisk::LexerException& exception)
{
std::cout << "Error: " << exception.what() << std::endl;
return EXIT_FAILURE;
}
break; break;
case obelisk::Lexer::kTokenFact : case obelisk::Lexer::kTokenFact :
parser->handleFact(kb); parser->handleFact(kb);

View File

@ -23,7 +23,14 @@ std::unique_ptr<obelisk::Lexer>& obelisk::Parser::getLexer()
int obelisk::Parser::getNextToken() int obelisk::Parser::getNextToken()
{ {
setCurrentToken(getLexer()->getToken()); try
{
setCurrentToken(getLexer()->getToken());
}
catch (obelisk::LexerException& exception)
{
throw;
}
return getCurrentToken(); return getCurrentToken();
} }
@ -328,6 +335,7 @@ void obelisk::Parser::parseFact(std::vector<obelisk::Fact>& facts)
else else
{ {
verb = getLexer()->getIdentifier(); verb = getLexer()->getIdentifier();
// TODO: make sure verb is alphabetic
getEntity = true; getEntity = true;
continue; continue;
} }
@ -361,7 +369,6 @@ void obelisk::Parser::handleFact(std::unique_ptr<obelisk::KnowledgeBase>& kb)
int verbId = 0; int verbId = 0;
for (auto& fact : facts) for (auto& fact : facts)
{ {
// TODO: doesn't work after first insert
std::vector<obelisk::Entity> entities {fact.getLeftEntity()}; std::vector<obelisk::Entity> entities {fact.getLeftEntity()};
kb->addEntities(entities); kb->addEntities(entities);
fact.setLeftEntity(entities.front()); fact.setLeftEntity(entities.front());
@ -373,7 +380,8 @@ void obelisk::Parser::handleFact(std::unique_ptr<obelisk::KnowledgeBase>& kb)
kb->getEntity(entity); kb->getEntity(entity);
if (entity.getId() == 0) if (entity.getId() == 0)
{ {
// TODO: throw an error here, it was not inserted, and doesn't exist in the database throw obelisk::ParserException(
"left entity could not be inserted into the database");
} }
else else
{ {
@ -391,7 +399,8 @@ void obelisk::Parser::handleFact(std::unique_ptr<obelisk::KnowledgeBase>& kb)
kb->getEntity(entity); kb->getEntity(entity);
if (entity.getId() == 0) if (entity.getId() == 0)
{ {
// TODO: throw an error here, it was not inserted, and doesn't exist in the database throw obelisk::ParserException(
"right entity could not be inserted into the database");
} }
else else
{ {
@ -405,14 +414,23 @@ void obelisk::Parser::handleFact(std::unique_ptr<obelisk::KnowledgeBase>& kb)
kb->addVerbs(verbs); kb->addVerbs(verbs);
if (verbs.front().getId() != 0) if (verbs.front().getId() != 0)
{ {
// The verb was inserted
fact.setVerb(verbs.front()); fact.setVerb(verbs.front());
verbId = fact.getVerb().getId(); verbId = fact.getVerb().getId();
} }
else else
{ {
// The verb is already already in the knowledge base obelisk::Verb verb = fact.getVerb();
// TODO: SELECT the verb and save it into verbId kb->getVerb(verb);
if (verb.getId() == 0)
{
throw obelisk::ParserException(
"verb could not be inserted into the database");
}
else
{
fact.setVerb(verb);
verbId = fact.getVerb().getId();
}
} }
} }
else else
@ -420,10 +438,19 @@ void obelisk::Parser::handleFact(std::unique_ptr<obelisk::KnowledgeBase>& kb)
fact.getVerb().setId(verbId); fact.getVerb().setId(verbId);
} }
// INSERT INTO fact
std::vector<obelisk::Fact> facts {fact}; std::vector<obelisk::Fact> facts {fact};
kb->addFacts(facts); kb->addFacts(facts);
fact = facts.front(); fact = facts.front();
if (fact.getId() == 0)
{
kb->getFact(fact);
if (fact.getId() == 0)
{
throw obelisk::ParserException(
"fact could not be inserted into the database");
}
}
} }
} }