Мне приходится иметь дело с действительно длинными целыми числами в текстовом формате - настолько длинными, что они не помещаются в 32-битное целое число.Мне нужно разобрать такой текст в
boost::variant<int, double>.
Так что, если есть целое число от длинного целого к большому, оно должно пойти в двойное число.Смотрите пример ниже.Он не анализирует пару имя-значение
MUESR1 = 411100000000000.
Как это можно исправить?
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <iterator>
namespace qi = boost::spirit::qi;
namespace spirit = boost::spirit;
namespace ascii = boost::spirit::ascii;
typedef boost::variant<int, double> VALUE;
typedef std::pair<std::string, VALUE> PAIR;
typedef std::map<std::string, VALUE> PAIRS;
template<typename Iterator>
struct parameters:qi::grammar<Iterator, PAIRS(), ascii::space_type>
{
qi::rule<Iterator, std::string(), ascii::space_type> m_sName;
qi::rule<Iterator, VALUE(), ascii::space_type> m_sValue;
qi::rule<Iterator, PAIR(), ascii::space_type> m_sNameValue;
qi::rule<Iterator, PAIRS(), ascii::space_type> m_sRoot;
qi::real_parser<double, qi::strict_real_policies<double> > m_sReal;
parameters(void)
:parameters::base_type(m_sRoot)
{ m_sName %= qi::lexeme[qi::char_("a-zA-Z_") >> *qi::char_("a-zA-z_0-9")];
m_sValue %= m_sReal | spirit::int_;
m_sNameValue %= m_sName >> qi::lit('=') >> m_sValue >> -qi::lit('\n');
m_sRoot %= m_sNameValue >> *m_sNameValue;
}
};
int main(int, char**)
{
static const char s_ap[] = "\
MUEPH1 = 7.014158 MUEPHW= -0.3 MUEPWP = 0.23 MUEPHL= -0.72 MUEPLP = 3.4 MUEPHS = 2.976E-07 MUEPSP = 5 VTMP= -1.8463 WVTH0= -1.01558 MUESR0 = 0.01256478438899837 MUESR1 = 411100000000000\n\
MUEPHW2 = 0 MUEPWP2 = 1\n";
parameters<const char*> sGrammar;
const char *pIter = s_ap;
const char *const pEnd = s_ap + sizeof s_ap - 1;
PAIRS sValues;
if (phrase_parse(pIter, pEnd, sGrammar, boost::spirit::ascii::space, sValues) && pIter == pEnd)
{ std::cerr << "parsing successful!" << std::endl;
for (const auto &r : sValues)
std::cout << r.first << "=" << std::scientific << r.second << std::endl;
}
else
{ std::cerr << "parsing failed!" << std::endl;
std::cerr << pIter << std::endl;
}
}