Last active
August 29, 2015 14:22
-
-
Save gordonwoodhull/dcbb332eea06dd3279b9 to your computer and use it in GitHub Desktop.
Parse graphviz graph description at C++ compile time using metaparse! (incomplete)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define MPLLIBS_LIMIT_SEQUENCE_SIZE 7 | |
#define MPLLIBS_LIMIT_STRING_SIZE 256 | |
#include <mpllibs/metaparse/string.hpp> | |
#include <mpllibs/metaparse/keyword.hpp> | |
#include <mpllibs/metaparse/token.hpp> | |
#include <mpllibs/metaparse/lit_c.hpp> | |
#include <mpllibs/metaparse/any.hpp> | |
#include <mpllibs/metaparse/alphanum.hpp> | |
#include <mpllibs/metaparse/sequence.hpp> | |
#include <mpllibs/metaparse/one_of.hpp> | |
#include <mpllibs/metaparse/empty.hpp> | |
#include <mpllibs/metaparse/build_parser.hpp> | |
#include <mpllibs/metaparse/entire_input.hpp> | |
#include <mpllibs/metaparse/foldr1.hpp> | |
#include <mpllibs/metaparse/foldlp.hpp> | |
#include <mpllibs/metaparse/return_.hpp> | |
#include <mpllibs/metaparse/transform.hpp> | |
#include <mpllibs/metaparse/middle_of.hpp> | |
#include <mpllibs/metaparse/last_of.hpp> | |
#include <boost/mpl/lambda.hpp> | |
#include <boost/mpl/push_front.hpp> | |
#include <boost/mpl/at.hpp> | |
using namespace mpllibs::metaparse; | |
namespace mpl = boost::mpl; | |
template<typename Parser, typename Default = void> using opt = one_of<Parser, return_<Default>>; | |
using graph_token = token<keyword<MPLLIBS_STRING("graph")>>; | |
using lbrace_token = token<lit_c<'{'>>; | |
using rbrace_token = token<lit_c<'}'>>; | |
using semi_token = token<lit_c<';'>>; | |
using lbracket_token = token<lit_c<'['>>; | |
using rbracket_token = token<lit_c<']'>>; | |
using comma_token = token<lit_c<','>>; | |
using equals_token = token<lit_c<'='>>; | |
// from grammar.hpp | |
typedef | |
token< | |
foldr1< | |
one_of<alphanum, lit_c<'_'> >, | |
string<>, | |
boost::mpl::lambda< | |
boost::mpl::push_front<boost::mpl::_1, boost::mpl::_2> | |
>::type | |
> | |
> | |
name_token; | |
using ID = name_token; | |
template<typename Name, typename Value> | |
struct attr_decl { | |
typedef attr_decl type; // why?; | |
}; | |
template<typename AttrDecl> | |
struct declare_attr { | |
typedef attr_decl<typename mpl::at_c<AttrDecl, 0>::type, typename mpl::at_c<AttrDecl, 2>::type> type; | |
}; | |
using attr = transform< | |
sequence<ID, equals_token, ID>, | |
mpl::quote1<declare_attr> | |
>; | |
using a_list = foldlp< | |
last_of<one_of<comma_token, semi_token>, attr>, | |
transform<attr, mpl::quote1<mpl::vector1>>, | |
mpl::quote2<mpl::push_back> | |
>; | |
using attr_list = middle_of<lbracket_token, a_list, rbracket_token>; | |
template<typename ID, typename Attrs> | |
struct node_decl { | |
typedef node_decl type; // why? | |
}; | |
template<typename NodeDecl> | |
struct declare_node { | |
typedef node_decl<typename mpl::at_c<NodeDecl, 0>::type, typename mpl::at_c<NodeDecl, 1>::type> type; | |
}; | |
using node_stmt = transform< | |
sequence<ID, opt<attr_list, mpl::vector<>>>, | |
mpl::quote1<declare_node> | |
>; | |
using arrow_token = token<keyword<MPLLIBS_STRING("->")>>; | |
template<typename Tail, typename Head, typename Attrs> | |
struct edge_decl { | |
typedef edge_decl type; //why? | |
}; | |
template<typename EdgeDecl> | |
struct declare_edge { | |
typedef edge_decl<typename mpl::at_c<EdgeDecl, 0>::type, | |
typename mpl::at_c<EdgeDecl, 2>::type, | |
typename mpl::at_c<EdgeDecl, 3>::type> type; | |
}; | |
using edge_stmt = transform< | |
sequence<ID, arrow_token, ID, opt<attr_list, mpl::vector<>>>, | |
mpl::quote1<declare_edge> | |
>; | |
using stmt = one_of<edge_stmt, node_stmt>; // not one_of<node_stmt, edge_stmt>; | |
using stmt_list = foldlp< | |
last_of<opt<semi_token>, stmt>, // not sequence<opt<semi_token>, stmt> | |
transform<stmt, mpl::quote1<mpl::vector1>>, | |
mpl::quote2<mpl::push_back> | |
>; | |
template<typename GraphDecl> | |
struct declare_graph : | |
mpl::pair<typename mpl::at_c<GraphDecl, 1>::type, typename mpl::at_c<GraphDecl, 3>::type> | |
{}; | |
using graph_parser = build_parser< | |
entire_input< | |
transform< | |
sequence< | |
graph_token, opt<ID, string<>>, lbrace_token, | |
stmt_list, | |
rbrace_token | |
>, | |
mpl::quote1<declare_graph> | |
> | |
>>; | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define PRINT(T) static_assert(T::dummy_type, "hello there") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "gvparse.hpp" | |
#include "test.hpp" | |
using test1 = graph_parser::apply<MPLLIBS_STRING("graph g { A [x=y]; B->C [y=z, w=a]; D->E; F; G->H }")>::type; | |
PRINT(test1); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "gvparse.hpp" | |
#include "test.hpp" | |
using test1 = graph_parser::apply<MPLLIBS_STRING("graph g { A [x=y]; \ | |
B->C [y=z, w=a]; \ | |
D->E; \ | |
F; \ | |
G->H [a=b, b=c, c=d, d=e, e=f, f=g] \ | |
}")>::type; | |
PRINT(test1); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "gvparse.hpp" | |
#include "test.hpp" | |
using test1 = graph_parser::apply<MPLLIBS_STRING("graph g { A [x=y]; \ | |
B->C [y=z, w=a]; \ | |
D->E; \ | |
F; \ | |
G->H [a=b, b=c, c=d, d=e, e=f, f=g]; \ | |
I->J; \ | |
J->K; \ | |
K->L; \ | |
L->M; \ | |
M->N [g=h, h=i, i=j, j=k, k=l]; \ | |
N->O; \ | |
O->P [l=m; m=n; n=o; o=p]; \ | |
P->Q; \ | |
Q->R \ | |
}")>::type; | |
PRINT(test1); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment