Select Git revision
PolynomialReconstruction.cpp
PugsParser.cpp 4.11 KiB
#include <PugsOStream.hpp>
#include <PugsParser.hpp>
#include <rang.hpp>
#include <pegtl.hpp>
#include <pegtl/analyze.hpp>
using namespace TAO_PEGTL_NAMESPACE;
namespace language
{
// clang-format off
struct comment
: sor< if_must<
string< '/', '/' >,
until< eolf >
>,
if_must<
string< '/', '*' >,
until< string< '*', '/' > >
>
> {};
struct ignored
: star< sor< space, comment> >{};
// struct ignored : star< space >{};
struct integer
: seq< opt< one< '+', '-' > >, plus< digit > >{};
struct INTEGER : seq< integer, ignored >{};
struct real
: seq< opt< one< '+',
'-' >
>,
sor< seq<
plus< digit >,
one < '.' >,
star< digit >
>,
seq<
one < '.' >,
plus< digit >
>
>,
opt<
seq<
one< 'E',
'e' >,
opt< one< '+',
'-' >
>,
plus<digit>
>
>
>{};
struct REAL : seq< real, ignored >{};
struct IDENTIFIER : seq <identifier, ignored> {};
struct expression : sor< REAL, INTEGER , IDENTIFIER> {};
struct EXPRESSION : seq< expression, ignored> {};
struct binary_op
: seq< EXPRESSION , one< '+' >, EXPRESSION> {};
struct semicol : one< ';' >{};
struct SEMICOL : seq< semicol , ignored > {};
struct instruction
: sor<seq< expression , SEMICOL >,
seq< binary_op, SEMICOL >,
SEMICOL>
{};
struct grammar
: must<ignored, star<instruction>,eof>{};
// clang-format on
template <typename Rule>
struct action : nothing<Rule>
{
};
template <>
struct action<integer>
{
template <typename Input>
static void
apply(const Input& in, std::string& v)
{
v += std::string("I:") + in.string() + std::string(" ;\n");
}
};
template <>
struct action<real>
{
template <typename Input>
static void
apply(const Input& in, std::string& v)
{
v += std::string("R:") + in.string() + std::string(" ;\n");
}
};
template <>
struct action<identifier>
{
template <typename Input>
static void
apply(const Input& in, std::string& v)
{
v += std::string("S:") + in.string() + std::string(" ;\n");
}
};
template <>
struct action<binary_op>
{
template <typename Input>
static void
apply(const Input& in, std::string& v)
{
v += "binary_op(" + in.string() + std::string(") ;\n");
}
};
template <typename Rule>
struct errors : public normal<Rule>
{
static const std::string error_message;
template <typename Input, typename... States>
static void
raise(const Input& in, States&&... /*unused*/)
{
throw parse_error(error_message, std::vector{in.position()});
}
};
template <typename Rule>
const std::string errors<Rule>::error_message = "parse error...";
template <>
const std::string errors<eolf>::error_message = "parse error expecting expression";
} // namespace language
void
parser(const std::string& filename)
{
std::string name;
const size_t grammar_issues = analyze<language::grammar>();
pout() << rang::fgB::yellow << "grammar_issues=" << rang::fg::reset << grammar_issues << '\n';
pout() << rang::style::bold << "Parsing file " << rang::style::reset << rang::style::underline << filename
<< rang::style::reset << " ...\n\n";
read_input in(filename);
try {
parse<language::grammar,
language::action //, language::errors
>(in, name);
}
catch (const parse_error& e) {
const auto p = e.positions.front();
perr() << rang::style::bold << p.source << ':' << p.line << ':' << p.byte_in_line << ": " << rang::style::reset
<< rang::fgB::red << "error: " << rang::fg::reset << rang::style::bold << e.what() << rang::style::reset
<< '\n'
<< in.line_at(p) << '\n'
<< std::string(p.byte_in_line, ' ') << rang::fgB::yellow << '^' << rang::fg::reset << std::endl;
std::exit(1);
}
pout() << "Parsed:\n" << name << std::endl;
}