2022-10-25 17:08:36 -03:00
|
|
|
#include "knowledge_base.h"
|
2022-10-17 22:26:36 -03:00
|
|
|
#include "lexer.h"
|
2023-02-16 02:26:14 -03:00
|
|
|
#include "lib/include/obelisk.h"
|
|
|
|
#include "lib/version.h"
|
2022-10-17 22:26:36 -03:00
|
|
|
#include "obelisk.h"
|
|
|
|
#include "parser.h"
|
|
|
|
|
2022-10-25 17:08:36 -03:00
|
|
|
#include <iomanip>
|
2022-10-17 22:26:36 -03:00
|
|
|
#include <iostream>
|
2022-10-25 17:08:36 -03:00
|
|
|
#include <limits>
|
2022-11-04 11:20:34 -03:00
|
|
|
#include <memory>
|
2022-10-17 22:26:36 -03:00
|
|
|
|
2023-02-13 23:03:31 -03:00
|
|
|
int obelisk::mainLoop(const std::vector<std::string>& sourceFiles, const std::string& kbFile)
|
2022-10-17 22:26:36 -03:00
|
|
|
{
|
2022-11-26 00:32:06 -03:00
|
|
|
std::unique_ptr<obelisk::KnowledgeBase> kb;
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
2023-02-08 10:17:58 -03:00
|
|
|
kb = std::unique_ptr<obelisk::KnowledgeBase> {new obelisk::KnowledgeBase(kbFile.c_str())};
|
2022-11-26 00:32:06 -03:00
|
|
|
}
|
|
|
|
catch (obelisk::KnowledgeBaseException& exception)
|
|
|
|
{
|
|
|
|
std::cout << exception.what() << std::endl;
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
2022-10-17 22:26:36 -03:00
|
|
|
|
2023-02-13 23:03:31 -03:00
|
|
|
size_t file = 0;
|
|
|
|
std::shared_ptr<obelisk::Lexer> lexer;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
lexer = std::shared_ptr<obelisk::Lexer> {new obelisk::Lexer(sourceFiles[file++])};
|
|
|
|
}
|
|
|
|
catch (obelisk::LexerException& exception)
|
|
|
|
{
|
|
|
|
std::cout << exception.what() << std::endl;
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
auto parser = std::unique_ptr<obelisk::Parser> {new obelisk::Parser(lexer)};
|
|
|
|
|
|
|
|
// prime the first token
|
2022-11-30 22:44:35 -03:00
|
|
|
try
|
|
|
|
{
|
|
|
|
parser->getNextToken();
|
|
|
|
}
|
|
|
|
catch (obelisk::LexerException& exception)
|
|
|
|
{
|
|
|
|
std::cout << "Error: " << exception.what() << std::endl;
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
2022-10-17 22:26:36 -03:00
|
|
|
|
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
switch (parser->getCurrentToken())
|
|
|
|
{
|
|
|
|
case obelisk::Lexer::kTokenEof :
|
2023-02-13 23:03:31 -03:00
|
|
|
// end of source file found, create a new lexer and pass it to the parser to use
|
|
|
|
if (file >= sourceFiles.size())
|
|
|
|
{
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|
|
|
|
try
|
|
|
|
{
|
|
|
|
lexer = std::shared_ptr<obelisk::Lexer> {new obelisk::Lexer(sourceFiles[file++])};
|
|
|
|
parser->setLexer(lexer);
|
|
|
|
// prime the first token in the parser
|
|
|
|
parser->getNextToken();
|
|
|
|
}
|
|
|
|
catch (obelisk::LexerException& exception)
|
|
|
|
{
|
|
|
|
std::cout << exception.what() << std::endl;
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ';' :
|
|
|
|
// semicolon found, the end of a statement
|
2022-11-30 22:44:35 -03:00
|
|
|
try
|
|
|
|
{
|
|
|
|
parser->getNextToken();
|
|
|
|
}
|
|
|
|
catch (obelisk::LexerException& exception)
|
|
|
|
{
|
|
|
|
std::cout << "Error: " << exception.what() << std::endl;
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
2022-10-17 22:26:36 -03:00
|
|
|
break;
|
2022-11-04 11:20:34 -03:00
|
|
|
case obelisk::Lexer::kTokenFact :
|
2022-11-26 00:32:06 -03:00
|
|
|
parser->handleFact(kb);
|
2022-11-04 11:20:34 -03:00
|
|
|
break;
|
|
|
|
case obelisk::Lexer::kTokenRule :
|
2022-11-26 00:32:06 -03:00
|
|
|
// parser->handleRule();
|
2022-11-04 11:20:34 -03:00
|
|
|
break;
|
|
|
|
case obelisk::Lexer::kTokenAction :
|
2023-02-16 00:35:29 -03:00
|
|
|
parser->handleAction(kb);
|
2022-11-04 11:20:34 -03:00
|
|
|
break;
|
2022-10-17 22:26:36 -03:00
|
|
|
default :
|
|
|
|
parser->getNextToken();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2022-11-26 00:32:06 -03:00
|
|
|
|
|
|
|
return EXIT_SUCCESS;
|
2022-10-17 22:26:36 -03:00
|
|
|
}
|
|
|
|
|
2023-02-13 23:03:31 -03:00
|
|
|
static void obelisk::showUsage()
|
2023-02-08 09:36:43 -03:00
|
|
|
{
|
|
|
|
std::cout << obelisk::usageMessage << std::endl;
|
|
|
|
}
|
|
|
|
|
2022-10-17 22:26:36 -03:00
|
|
|
int main(int argc, char** argv)
|
|
|
|
{
|
2023-02-08 09:36:43 -03:00
|
|
|
std::vector<std::string> sourceFiles;
|
|
|
|
std::string kbFile = "obelisk.kb";
|
|
|
|
|
|
|
|
while (true)
|
2022-10-17 22:26:36 -03:00
|
|
|
{
|
2023-02-08 09:36:43 -03:00
|
|
|
int option_index = 0;
|
|
|
|
switch (getopt_long(argc, argv, "k:hv", obelisk::long_options, &option_index))
|
|
|
|
{
|
|
|
|
case 'k' :
|
|
|
|
kbFile = std::string(optarg);
|
|
|
|
continue;
|
|
|
|
case 'h' :
|
|
|
|
obelisk::showUsage();
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
break;
|
|
|
|
case 'v' :
|
2023-02-16 02:27:24 -03:00
|
|
|
std::cout << "obelisk " << obelisk::version << std::endl;
|
2023-02-08 09:36:43 -03:00
|
|
|
return EXIT_SUCCESS;
|
|
|
|
break;
|
|
|
|
default :
|
|
|
|
obelisk::showUsage();
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case -1 :
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
2022-10-17 22:26:36 -03:00
|
|
|
}
|
|
|
|
|
2023-02-08 09:36:43 -03:00
|
|
|
if (optind < argc)
|
2022-10-25 17:08:36 -03:00
|
|
|
{
|
2023-02-08 09:36:43 -03:00
|
|
|
while (optind < argc)
|
|
|
|
{
|
|
|
|
sourceFiles.push_back(argv[optind++]);
|
|
|
|
}
|
2022-11-04 11:20:34 -03:00
|
|
|
}
|
2023-02-08 09:36:43 -03:00
|
|
|
|
|
|
|
if (sourceFiles.size() == 0)
|
2022-11-04 11:20:34 -03:00
|
|
|
{
|
2023-02-08 09:36:43 -03:00
|
|
|
obelisk::showUsage();
|
2022-11-04 11:20:34 -03:00
|
|
|
return EXIT_FAILURE;
|
2023-02-08 09:36:43 -03:00
|
|
|
}
|
|
|
|
|
2023-02-08 10:17:58 -03:00
|
|
|
return obelisk::mainLoop(sourceFiles, kbFile);
|
2022-10-17 22:26:36 -03:00
|
|
|
}
|