1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
|
#include <iostream>
#define FUSION_MAX_VECTOR_SIZE 12
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_int.hpp>
#include <boost/spirit/include/qi_no_skip.hpp>
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
struct face {
int i1,i2,i3;
int n1,n2,n3;
int m1,m2,m3;
int t1,t2,t3;
};
BOOST_FUSION_ADAPT_STRUCT(
face,
(int, i1) (int, i2) (int, i3)
(int, n1) (int, n2) (int, n3)
(int, m1) (int, m2) (int, m3)
(int, t1) (int, t2) (int, t3)
)
// have to use this macro instead of the regular auto for named micro-parsers, until Spirit V3
#define BOOST_SPIRIT_AUTO(domain_, name, expr) \
typedef BOOST_TYPEOF(expr) name##expr_type; \
BOOST_SPIRIT_ASSERT_MATCH(boost::spirit::domain_::domain, name##expr_type); \
BOOST_AUTO(name, boost::proto::deep_copy(expr)); \
int main()
{
std::string input("f 1/2/3 4/5/6 7/8/9\n"
"f 10/11/12 13/14/15 16/17/18 19/20/21\n"
"f 22/23/ 24/25/ 26/27/\n"
"f 28/29/ 30/31/ 32/33/ 34/35/\n"
"f 36//37 38//39 40//41\n"
"f 42//43 44//45 46//47 48//49\n"
"f 50 51 52\n"
"f 53 54 55 56\n");
std::vector<face> result;
BOOST_SPIRIT_AUTO(qi, optint, qi::no_skip[qi::int_] | qi::attr(-1));
BOOST_SPIRIT_AUTO(qi, triple, qi::int_ >> ( ('/' >> optint >> '/') | qi::attr(-1) ) >> optint);
qi::phrase_parse(input.begin(), input.end(),
*( ('f' >> triple >> triple >> triple >> triple )
| ('f' >> triple >> triple >> triple >> qi::attr(-1) >> qi::attr(-1) >> qi::attr(-1) )
),
ascii::space, result );
for(face& f: result)
std::cout << "{ " << f.i1 << ',' << f.i2 << ',' << f.i3 << '\n'
<< " " << f.n1 << ',' << f.n2 << ',' << f.n3 << '\n'
<< " " << f.m1 << ',' << f.m2 << ',' << f.m3 << '\n'
<< " " << f.t1 << ',' << f.t2 << ',' << f.t3 << " }\n";
}
|