#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>
#include <boost/spirit/include/qi_eol.hpp>
#include <boost/spirit/include/qi_eoi.hpp>
#include <boost/spirit/include/qi_eps.hpp>
#include <boost/spirit/include/qi_symbols.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <boost/foreach.hpp>
#include <iostream>
#include <string>
#include <complex>
namespace client
{
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phoenix = boost::phoenix;
///
// Our employee struct
///
//[tutorial_employee_struct
struct employee
{
int age;
std::string surname;
std::string forename;
double salary;
};
struct employee_list
{
std::vector<employee> m_list;
};
//]
}
// We need to tell fusion about our employee struct
// to make it a first-class fusion citizen. This has to
// be in global scope.
//[tutorial_employee_adapt_struct
BOOST_FUSION_ADAPT_STRUCT(
client::employee,
(int, age)
(std::string, surname)
(std::string, forename)
(double, salary)
)
BOOST_FUSION_ADAPT_STRUCT(
client::employee_list,
(std::vector<client::employee>,m_list)
)
//]
namespace client
{
///
// Our employee parser
///
//[tutorial_employee_parser
template <typename Iterator>
struct employee_parser : qi::grammar<Iterator, client::employee_list(), ascii::space_type>
{
employee_parser() : employee_parser::base_type(new_start)
{
using qi::lit;
using qi::lexeme;
using ascii::char_;
using ascii::string;
using namespace qi::labels;
using qi::eol;
using qi::eoi;
using qi::eps;
using qi::int_;
using phoenix::at_c;
using phoenix::push_back;
using phoenix::ref;
using qi::double_;
quoted_string %= lexeme['"' >> +(char_ - '"') >> '"'];
start %=
lit("employee")
>> '{'
>> int_ >> ','
>> quoted_string >> ','
>> quoted_string >> ','
>> double_
>> '}'
;
// vec_start = start[push_back(at_c<0>(_val), _1)] ;
new_start =+start[push_back(at_c<0>(_val), _1)] ;
}
qi::rule<Iterator, std::string(), ascii::space_type> quoted_string;
qi::rule<Iterator, employee(), ascii::space_type> start;
qi::rule<Iterator, std::vector<employee>> vec_start;
qi::rule<Iterator, client::employee_list(), ascii::space_type> new_start;
};
//]
}
// Main program
int
main()
{
std::cout << "/\n\n";
std::cout << "\t\tAn employee parser for Spirit...\n\n";
std::cout << "/\n\n";
std::cout
<< "Give me an employee of the form :"
<< "employee{age, \"surname\", \"forename\", salary } \n";
std::cout << "Type [q or Q] to quit\n\n";
using boost::spirit::ascii::space;
typedef std::string::const_iterator iterator_type;
typedef client::employee_parser<iterator_type> employee_parser;
employee_parser g; // Our grammar
//CW2A test_cta("aa.txt");
file<CHAR> tempfile("aa.txt");
// xLog(LOG_NORMAL,_T("\n-------%d---%d---%d---"),*tempfile.data(),*(tempfile.data()+1),*(tempfile.data()+2));
// xLog(LOG_NORMAL,_T("\n-------%d"),temp_str_tekla.size());
// xLog(LOG_NORMAL,_T("\n-----------%s"),temp_str_tekla.c_str());
/* std::string temp_str_tekla(tempfile.data());*/
std::string str(tempfile.data());
// while (getline(std::cin, str))
// {
// if (str.empty() || str[0] == 'q' || str[0] == 'Q')
// break;
client::employee emp;
client::employee_list emp_list;
std::string::const_iterator iter = str.begin();
std::string::const_iterator end = str.end();
bool r = phrase_parse(iter, end, g, space, emp_list);
if (r && iter == end)
{
// std::cout << boost::fusion::tuple_open('[');
// std::cout << boost::fusion::tuple_close(']');
// std::cout << boost::fusion::tuple_delimiter(", ");
std::cout << "-------------------------\n";
std::cout << "Parsing succeeded\n";
/* std::cout << "got: " << boost::fusion::as_vector(emp) << std::endl;*/
std::cout << "\n-------------------------\n";
}
else
{
std::cout << "-------------------------\n";
std::cout << "Parsing failed\n";
std::cout << "-------------------------\n";
}
// }
std::cout << "Bye... :-) \n\n";
return 0;
}
测试文本aa.txt
employee{ 22, "surname1", "forename1", 1341}
employee{ 23, "surname2", "forename2", 2341}
employee{ 24, "surname3", "forename3", 3341}
employee{ 25, "surname4", "forename4", 4341}
是这样的。
_1 解析出来的第一个值
at_c<0>(_val) 当前被解析的容器的第一个变量,如果有多个那么 at_c<n>(_val)