template<typename Iter>
struct Parser : qi::grammar<Iter, File ()>
{
qi::rule<Iter, File ()> Start_;
qi::rule<Iter, Group ()> Group_;
qi::rule<Iter, std::string ()> GroupName_;
qi::rule<Iter, std::string ()> Lang_;
qi::rule<Iter, void ()> KeyValSep_;
qi::rule<Iter, std::string ()> LineValSingle_;
qi::rule<Iter, FieldVal_t ()> LineVal_;
qi::rule<Iter, Field ()> Line_;
qi::rule<Iter, void ()> Comment_;
Parser ()
: Parser::base_type (Start_)
{
auto eol = qi::lit ("\n");
Comment_ %= qi::lit ("#") >> *(qi::char_) >> eol;
Lang_ %= '[' >> qi::lexeme[+(qi::char_ ("a-zA-Z0-9"))] >> ']';
KeyValSep_ %= *(qi::lit (' ')) >> '=' >> *(qi::lit (' '));
LineValSingle_ %= qi::lexeme[+((qi::lit ("\\;") | (qi::char_ - ';' - '\r' - '\n')))];
LineVal_ %= LineValSingle_ | *(LineValSingle_ >> ';');
Line_ %= qi::lexeme[+(qi::char_ ("a-zA-Z0-9"))] >>
-Lang_ >>
KeyValSep_ >>
LineVal_ >>
eol;
GroupName_ %= '[' >> qi::lexeme[+(qi::char_ ("a-zA-Z0-9 "))] >> ']';
Group_ %= *Comment_ >>
GroupName_ >> eol >>
*(Comment_ | Line_);
Start_ %= Group_ >> *Group_;
qi::on_error<qi::fail> (Start_,
std::cout << phoenix::val ("Error! Expecting") << qi::_4
<< phoenix::val (" here: \"") << phoenix::construct<std::string> (qi::_3, qi::_2)
<< phoenix::val ("\"") << std::endl);
}
};