feature/error_handling #9
@ -48,11 +48,20 @@ int obelisk::Lexer::getToken()
|
||||
return kTokenIdentifier;
|
||||
}
|
||||
|
||||
if (isdigit(lastChar) || lastChar == '.')
|
||||
if (isdigit(lastChar))
|
||||
{
|
||||
bool firstPeriod = false;
|
||||
std::string numberStr;
|
||||
do
|
||||
{
|
||||
if (firstPeriod && lastChar == '.')
|
||||
{
|
||||
throw obelisk::LexerException("invalid double value");
|
||||
}
|
||||
else if (!firstPeriod && lastChar == '.')
|
||||
{
|
||||
firstPeriod = true;
|
||||
}
|
||||
numberStr += lastChar;
|
||||
lastChar = getchar();
|
||||
}
|
||||
|
23
src/lexer.h
23
src/lexer.h
@ -3,7 +3,6 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
// TODO: add error handling
|
||||
namespace obelisk
|
||||
{
|
||||
class Lexer
|
||||
@ -41,6 +40,28 @@ namespace obelisk
|
||||
const std::string& getIdentifier();
|
||||
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
|
||||
|
||||
#endif
|
||||
|
@ -26,7 +26,15 @@ static int mainLoop()
|
||||
|
||||
// Prime the first token.
|
||||
fprintf(stderr, "ready> ");
|
||||
try
|
||||
{
|
||||
parser->getNextToken();
|
||||
}
|
||||
catch (obelisk::LexerException& exception)
|
||||
{
|
||||
std::cout << "Error: " << exception.what() << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
@ -40,7 +48,15 @@ static int mainLoop()
|
||||
<< parser->getLexer()->getIdentifier() << std::endl;
|
||||
std::cout << "Num: " << parser->getLexer()->getNumberValue()
|
||||
<< std::endl;
|
||||
try
|
||||
{
|
||||
parser->getNextToken();
|
||||
}
|
||||
catch (obelisk::LexerException& exception)
|
||||
{
|
||||
std::cout << "Error: " << exception.what() << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
break;
|
||||
case obelisk::Lexer::kTokenFact :
|
||||
parser->handleFact(kb);
|
||||
|
@ -22,8 +22,15 @@ std::unique_ptr<obelisk::Lexer>& obelisk::Parser::getLexer()
|
||||
}
|
||||
|
||||
int obelisk::Parser::getNextToken()
|
||||
{
|
||||
try
|
||||
{
|
||||
setCurrentToken(getLexer()->getToken());
|
||||
}
|
||||
catch (obelisk::LexerException& exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
return getCurrentToken();
|
||||
}
|
||||
|
||||
@ -328,6 +335,7 @@ void obelisk::Parser::parseFact(std::vector<obelisk::Fact>& facts)
|
||||
else
|
||||
{
|
||||
verb = getLexer()->getIdentifier();
|
||||
// TODO: make sure verb is alphabetic
|
||||
getEntity = true;
|
||||
continue;
|
||||
}
|
||||
@ -361,7 +369,6 @@ void obelisk::Parser::handleFact(std::unique_ptr<obelisk::KnowledgeBase>& kb)
|
||||
int verbId = 0;
|
||||
for (auto& fact : facts)
|
||||
{
|
||||
// TODO: doesn't work after first insert
|
||||
std::vector<obelisk::Entity> entities {fact.getLeftEntity()};
|
||||
kb->addEntities(entities);
|
||||
fact.setLeftEntity(entities.front());
|
||||
@ -373,7 +380,8 @@ void obelisk::Parser::handleFact(std::unique_ptr<obelisk::KnowledgeBase>& kb)
|
||||
kb->getEntity(entity);
|
||||
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
|
||||
{
|
||||
@ -391,7 +399,8 @@ void obelisk::Parser::handleFact(std::unique_ptr<obelisk::KnowledgeBase>& kb)
|
||||
kb->getEntity(entity);
|
||||
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
|
||||
{
|
||||
@ -405,14 +414,23 @@ void obelisk::Parser::handleFact(std::unique_ptr<obelisk::KnowledgeBase>& kb)
|
||||
kb->addVerbs(verbs);
|
||||
if (verbs.front().getId() != 0)
|
||||
{
|
||||
// The verb was inserted
|
||||
fact.setVerb(verbs.front());
|
||||
verbId = fact.getVerb().getId();
|
||||
}
|
||||
else
|
||||
{
|
||||
// The verb is already already in the knowledge base
|
||||
// TODO: SELECT the verb and save it into verbId
|
||||
obelisk::Verb verb = fact.getVerb();
|
||||
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
|
||||
@ -420,10 +438,19 @@ void obelisk::Parser::handleFact(std::unique_ptr<obelisk::KnowledgeBase>& kb)
|
||||
fact.getVerb().setId(verbId);
|
||||
}
|
||||
|
||||
// INSERT INTO fact
|
||||
std::vector<obelisk::Fact> facts {fact};
|
||||
kb->addFacts(facts);
|
||||
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