Skip to content
Snippets Groups Projects
Commit 5a7687e1 authored by Stéphane Del Pino's avatar Stéphane Del Pino
Browse files

Simple grammar tests

- read integer and real numbers
- numbers must be followed by semi-column (instructions)
- spaces and comments are consumed silently
- test error message improvements (rang)
parent e36efbb4
Branches
Tags
1 merge request!12Feature/language
#include <PastisParser.hpp> #include <PastisParser.hpp>
#include <iostream> #include <iostream>
#include <rang.hpp>
#define TAO_PEGTL_NAMESPACE language #define TAO_PEGTL_NAMESPACE language
#include <pegtl.hpp> #include <pegtl.hpp>
#include <pegtl/analyze.hpp>
namespace language namespace language
{ {
using namespace tao::language; using namespace tao::language;
// clang-format off // clang-format off
//struct prefix : string< 'H', 'e', 'l', 'l', 'o', ',', ' ' > {};
struct prefix : TAO_PEGTL_STRING("Hello, ") {}; struct comment
struct name : plus< alpha > {}; : 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 struct grammar
: must< prefix, name, star< sor< space, digit, string < '+' >, string < '-' >, string < '/' >, string < '*' > > >, one< '!' >, eof > : must<star<instruction>,eof>{};
{
};
// clang-format on // clang-format on
template< typename Rule > template< typename Rule >
struct action struct action : nothing< Rule > {};
: nothing< Rule >
template<>
struct 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<> template<>
struct action< name > struct action< real >
{ {
template< typename Input > template< typename Input >
static void apply( const Input& in, std::string& v ) static void apply( const Input& in, std::string& v )
{ {
v = in.string(); 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) { void parser(const std::string& filename) {
std::string name; std::string name;
const size_t grammar_issues = language::analyze< language::grammar >();
std::cout << "grammar_issues=" << grammar_issues << '\n';
language::read_input in(filename); language::read_input in(filename);
language::parse< language::grammar, language::action >( in, name ); try {
language::parse< language::grammar, language::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_as_string( p ) << '\n'
<< std::string( p.byte_in_line, ' ' )
<< rang::fgB::yellow << '^' << rang::fg::reset
<< std::endl;
std::exit(1);
}
std::cout << name << " -> ";
std::cout << "Good bye, " << name << "!" << std::endl; std::cout << "Good bye, " << name << "!" << std::endl;
std::exit(0); std::exit(0);
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment