obelisk/src/main.cpp

191 lines
5.0 KiB
C++
Raw Normal View History

#include "knowledge_base.h"
2022-10-17 22:26:36 -03:00
#include "lexer.h"
#include "main.h"
2022-10-17 22:26:36 -03:00
#include "obelisk.h"
#include "parser.h"
#include "version.h"
2022-10-17 22:26:36 -03:00
#include <iomanip>
2022-10-17 22:26:36 -03:00
#include <iostream>
#include <limits>
#include <memory>
2022-10-17 22:26:36 -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
{
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
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
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 :
// 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
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;
case obelisk::Lexer::kTokenFact :
2023-02-19 01:03:35 -03:00
try
{
parser->handleFact(kb);
}
catch (obelisk::ParserException& exception)
{
std::cout << "Error: " << exception.what() << std::endl;
return EXIT_FAILURE;
}
break;
case obelisk::Lexer::kTokenRule :
2023-02-19 01:03:35 -03:00
try
{
parser->handleRule(kb);
}
catch (obelisk::ParserException& exception)
{
std::cout << "Error: " << exception.what() << std::endl;
return EXIT_FAILURE;
}
break;
case obelisk::Lexer::kTokenAction :
2023-02-19 01:03:35 -03:00
try
{
parser->handleAction(kb);
}
catch (obelisk::ParserException& exception)
{
std::cout << "Error: " << exception.what() << std::endl;
return EXIT_FAILURE;
}
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
}
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))
2023-02-08 09:36:43 -03:00
{
case 'k' :
kbFile = std::string(optarg);
continue;
case 'h' :
obelisk::showUsage();
return EXIT_SUCCESS;
break;
case 'v' :
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)
{
2023-02-08 09:36:43 -03:00
while (optind < argc)
{
sourceFiles.push_back(argv[optind++]);
}
}
2023-02-08 09:36:43 -03:00
if (sourceFiles.size() == 0)
{
2023-02-08 09:36:43 -03:00
obelisk::showUsage();
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
}