diff --git a/src/lexer.cpp b/src/lexer.cpp index cd62d75..5627689 100644 --- a/src/lexer.cpp +++ b/src/lexer.cpp @@ -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(); } diff --git a/src/lexer.h b/src/lexer.h index c82b949..9c4308d 100644 --- a/src/lexer.h +++ b/src/lexer.h @@ -3,7 +3,6 @@ #include -// 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 diff --git a/src/obelisk.cpp b/src/obelisk.cpp index 7586d95..8339996 100644 --- a/src/obelisk.cpp +++ b/src/obelisk.cpp @@ -26,7 +26,15 @@ static int mainLoop() // Prime the first token. fprintf(stderr, "ready> "); - parser->getNextToken(); + 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; - parser->getNextToken(); + 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); diff --git a/src/parser.cpp b/src/parser.cpp index 518786b..37e9a09 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -23,7 +23,14 @@ std::unique_ptr& obelisk::Parser::getLexer() int obelisk::Parser::getNextToken() { - setCurrentToken(getLexer()->getToken()); + try + { + setCurrentToken(getLexer()->getToken()); + } + catch (obelisk::LexerException& exception) + { + throw; + } return getCurrentToken(); } @@ -328,6 +335,7 @@ void obelisk::Parser::parseFact(std::vector& 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& kb) int verbId = 0; for (auto& fact : facts) { - // TODO: doesn't work after first insert std::vector entities {fact.getLeftEntity()}; kb->addEntities(entities); fact.setLeftEntity(entities.front()); @@ -373,7 +380,8 @@ void obelisk::Parser::handleFact(std::unique_ptr& 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& 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& 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& kb) fact.getVerb().setId(verbId); } - // INSERT INTO fact std::vector 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"); + } + } } }