feature/error_handling #9
@ -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();
|
||||||
}
|
}
|
||||||
|
23
src/lexer.h
23
src/lexer.h
@ -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
|
||||||
|
@ -26,7 +26,15 @@ static int mainLoop()
|
|||||||
|
|
||||||
// Prime the first token.
|
// Prime the first token.
|
||||||
fprintf(stderr, "ready> ");
|
fprintf(stderr, "ready> ");
|
||||||
|
try
|
||||||
|
{
|
||||||
parser->getNextToken();
|
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;
|
||||||
|
try
|
||||||
|
{
|
||||||
parser->getNextToken();
|
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);
|
||||||
|
@ -23,7 +23,14 @@ std::unique_ptr<obelisk::Lexer>& obelisk::Parser::getLexer()
|
|||||||
|
|
||||||
int obelisk::Parser::getNextToken()
|
int obelisk::Parser::getNextToken()
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
setCurrentToken(getLexer()->getToken());
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user