Skip to content

Instantly share code, notes, and snippets.

@sehe
Last active January 21, 2017 15:13
Show Gist options
  • Save sehe/a7d536e5987ad07bb87496348eead2d1 to your computer and use it in GitHub Desktop.
Save sehe/a7d536e5987ad07bb87496348eead2d1 to your computer and use it in GitHub Desktop.
#pragma once
#include <vector>
#include <string>
#include <boost/fusion/include/adapt_struct.hpp>
namespace ast{
namespace x3 = boost::spirit::x3;
struct Enum {
std::string _name;
std::vector<std::string> _elements;
};
}
BOOST_FUSION_ADAPT_STRUCT(ast::Enum, _name, _elements)
#pragma once
#include <boost/spirit/home/x3.hpp>
namespace parser{
namespace x3 = boost::spirit::x3;
typedef std::string::const_iterator iterator_type;
typedef x3::phrase_parse_context<x3::ascii::space_type>::type context_type;
}
#include "enum_def.hpp"
#include "config.hpp"
namespace parser { namespace impl {
BOOST_SPIRIT_INSTANTIATE(enum_type, iterator_type, context_type)
}}
namespace parser {
const impl::enum_type& enum_parser()
{
return impl::enum_parser;
}
}
#pragma once
#include <boost/spirit/home/x3.hpp>
#include "ast.hpp"
namespace parser{ namespace impl{
namespace x3=boost::spirit::x3;
typedef x3::rule<class enum_class, ast::Enum> enum_type;
BOOST_SPIRIT_DECLARE(enum_type)
}}
namespace parser{
const impl::enum_type& enum_parser();
}
#pragma once
#include "identifier.hpp"
#include "enum.hpp"
#include "ast.hpp"
namespace parser{ namespace impl{
namespace x3=boost::spirit::x3;
const enum_type enum_parser = "enum";
namespace{
const auto& identifier = parser::identifier();
}
auto const enum_parser_def =
"enum"
> identifier
> "{"
> identifier % ","
>"}";
BOOST_SPIRIT_DEFINE(enum_parser)
}}
#pragma once
#include "id.hpp"
#include "ast.hpp"
namespace parser {
namespace x3=boost::spirit::x3;
typedef x3::rule<class enum_class, ast::Enum> enum_type;
const enum_type enum_parser = "enum";
auto const enum_parser_def =
"enum"
> identifier
> "{"
> identifier % ","
>"}";
BOOST_SPIRIT_DEFINE(enum_parser)
}
#pragma once
#include <boost/spirit/home/x3.hpp>
namespace parser{
namespace x3=boost::spirit::x3;
typedef x3::rule<class identifier_class, std::string> identifier_type;
const identifier_type identifier = "identifier";
auto const identifier_def = x3::lexeme[
((x3::alpha | '_') >> *(x3::alnum | '_'))
];
BOOST_SPIRIT_DEFINE(identifier)
}
#pragma once
#include <boost/spirit/home/x3.hpp>
namespace parser{ namespace impl{
namespace x3=boost::spirit::x3;
typedef x3::rule<class identifier_class, std::string> identifier_type;
BOOST_SPIRIT_DECLARE(identifier_type)
}}
namespace parser{
const impl::identifier_type& identifier();
}
#pragma once
#include <boost/spirit/home/x3.hpp>
#include "identifier.hpp"
namespace parser{ namespace impl{
namespace x3=boost::spirit::x3;
const identifier_type identifier = "identifier";
auto const identifier_def = x3::lexeme[
((x3::alpha | '_') >> *(x3::alnum | '_'))
];
BOOST_SPIRIT_DEFINE(identifier)
}}
#include <boost/spirit/home/x3.hpp>
#include "ast.hpp"
#include "enum.hpp"
namespace x3 = boost::spirit::x3;
template<typename Parser, typename Attribute>
bool test(const std::string& str, Parser&& p, Attribute&& attr)
{
using iterator_type = std::string::const_iterator;
iterator_type in = str.begin();
iterator_type end = str.end();
bool ret = x3::phrase_parse(in, end, p, x3::ascii::space, attr);
ret &= (in == end);
return ret;
}
int main(){
ast::Enum attr;
test("enum foo{foo,bar}", parser::enum_parser(), attr);
test("enum {foo,bar}", parser::enum_parser(), attr);
}
all: test
CXX=clang++
CPPFLAGS=-std=c++14 -O2 -Wall -pedantic -march=native
#CPPFLAGS+=-fsanitize=address,undefined
CPPFLAGS+=-I ~/custom/boost
test: main.o identifier.o enum.o
$(CXX) $(CPPFLAGS) -o $@ $^ $(LDFLAGS)
%.o: %.cpp
$(CXX) $(CPPFLAGS) $^ -o $@ -c
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::spirit::x3::expectation_failure<__gnu_cxx::__normal_iterator<char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >'
what(): boost::spirit::x3::expectation_failure
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment