boost 中spirit 连续解析 employee 成容器变量

1 篇文章 0 订阅
1 篇文章 0 订阅

#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)
 
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值