#include "ParseFile.h"
#include "Parser.h"
#include <print>
#undef PROGNAME
#ifdef _WIN32
#define PROGNAME "grammarstrip.exe"
#else
#define PROGNAME "grammarstrip"
#endif
enum
{
MAIN_SUCCESS =0,
MAIN_ARG_ERROR,
MAIN_NOT_ACCEPTED,
MAIN_PARSE_ERROR,
MAIN_CAUGHT
};
struct C_LexAssoc
{
std::string m_Lex;
std::string m_Assoc;
};
typedef std::multimap<size_t,C_LexAssoc> C_Weight2Lex;
int main(int argc, const char* argv[])
{
"\t1. <Grammar> is a grammar definition file.\n"
"\t2. Print raw production rules to standard output.\n"};
C_Paths inc_dirs;
.add_flag("include_dir", 'I', "Search path of #include directive within <Grammar>",
[&](auto s){
for (std::string line; std::getline(in, line, ':'); inc_dirs.emplace_back(line));
});
auto ret = ezargs.
parse(argc, argv);
if (!ret)
{
std::print("{}\n", ret.message());
return MAIN_ARG_ERROR;
}
try
{
std::ios_base::sync_with_stdio(true);
C_BNFContext c{inc_dirs};
Main::C_BNFParser parser{c};
parseFile(argv[1], parser, TID_EOF);
if (!parser.accepted())
{
std::print("Not accepted on EOF\n");
return MAIN_NOT_ACCEPTED;
}
if (c.m_ErrorTotal[LL_ERROR] || c.m_ErrorTotal[LL_FATAL])
return MAIN_PARSE_ERROR;
if (!c.priorityMap().empty())
{
C_Weight2Lex w2l;
for (auto& i: c.priorityMap())
{
C_LexAssoc t;
for (auto j: c.lex2ID())
if (j.second == i.first)
{
t.m_Lex = '$' + j.first;
goto SetAssoc;
}
for (auto &j: c.generatedLexes())
if (j.second == i.first)
{
goto SetAssoc;
}
t.m_Lex = {'\"', char(i.first), '\"'};
SetAssoc:
switch (i.second.m_Assoc)
{
case ASSOC_NONE:
t.m_Assoc ="assoc";
break;
case LEFT2RIGHT:
t.m_Assoc ="left";
break;
case RIGHT2LEFT:
t.m_Assoc ="right";
break;
}
w2l.emplace(i.second.m_Weight, t);
}
for (auto &i: w2l)
std::print("{}\t{}\t{}\n", i.second.m_Lex, i.second.m_Assoc, i.first);
std::print("\n");
}
for (auto &i: c.productions())
std::print("{}\n", i.str());
return MAIN_SUCCESS;
}
catch (const std::exception &t)
{
std::print(
"{}: {} ... \n",
HRTN(t), t.what());
return MAIN_CAUGHT;
}
catch (...)
{
std::print("Unknown exception\r\n");
return MAIN_CAUGHT;
}
}
C_ErrorOrIndex parse(std::integral auto argc, const char *const argv[]) const
C_EZArgs & position_args(const std::ranges::forward_range auto &arg_names, const std::ranges::forward_range auto &count_optionals, bool unlimited=false)
THE common namespace of bux library.
std::string asciiLiteral(uint32_t utf32)