#include <PastisParser.hpp> #include <iostream> #include <rang.hpp> #define TAO_PEGTL_NAMESPACE language #include <pegtl.hpp> #include <pegtl/analyze.hpp> namespace language { using 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 expression : sor< REAL, INTEGER > {}; struct semicol : one< ';' >{}; struct SEMICOL : seq< semicol , ignored > {}; struct instruction : sor<seq< expression , SEMICOL>, SEMICOL> {}; struct grammar : must<ignored, star<instruction>,eof>{}; // clang-format on template< typename Rule > struct my_action : nothing< Rule > {}; template<> struct my_action< integer > { template< typename Input > static void apply( const Input& in, std::string& v ) { if (v.size() > 0) { v += std::string(", I:") + in.string(); } else { v = std::string("I:") + in.string(); } } }; template<> struct my_action< real > { template< typename Input > static void apply( const Input& in, std::string& v ) { if (v.size() > 0) { v += std::string(", R:") + in.string(); } else { v = std::string("R:") + in.string(); } } }; 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"; } void parser(const std::string& filename) { std::string name; const size_t grammar_issues = language::analyze< language::grammar >(); std::cout << "grammar_issues=" << grammar_issues << '\n'; language::read_input in(filename); try { language::parse< language::grammar, language::my_action//, language::errors >( in, name ); } catch(const language::parse_error& e) { const auto p = e.positions.front(); std::cerr << 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); } std::cout << "Good bye, " << name << "!" << std::endl; std::exit(0); }