I'm trying to make a little program to parse the cpu usage info from /proc/stat using Boost.Spirit. It is mostly working, but I can't get my grammar to compile when using repeat. What am I missing?
The whole code:
#include <vector>
#include "boost/fusion/include/adapt_struct.hpp"
#define BOOST_SPIRIT_DEBUG
#include "boost/spirit/include/qi.hpp"
#include "boost/iostreams/device/mapped_file.hpp"
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
struct Cpu
{
unsigned int user;
unsigned int nice;
unsigned int system;
unsigned int idle;
unsigned int iowait;
unsigned int irq;
unsigned int softirq;
unsigned int steal;
unsigned int guest;
unsigned int guest_nice;
};
BOOST_FUSION_ADAPT_STRUCT(
Cpu,
(unsigned int, user)
(unsigned int, nice)
(unsigned int, system)
(unsigned int, idle)
(unsigned int, iowait)
(unsigned int, irq)
(unsigned int, softirq)
(unsigned int, steal)
(unsigned int, guest)
(unsigned int, guest_nice)
)
template< typename Iter, typename Skip = ascii::blank_type >
struct Cpu_parser : qi::grammar< Iter, Cpu(), Skip >
{
qi::rule< Iter, Cpu(), Skip > start;
Cpu_parser() : Cpu_parser::base_type(start)
{
using namespace qi;
start = lexeme[lit("cpu") >> omit[-uint_]] >> repeat(10)[uint_];
//start = lexeme[lit("cpu") >> omit[-uint_]] >> uint_ >> uint_ >> uint_ >> uint_ >> uint_ >> uint_ >> uint_ >> uint_ >> uint_ >> uint_;
BOOST_SPIRIT_DEBUG_NODE(start);
}
};
int main(int argc, char** argv)
{
std::vector< Cpu > cpus;
{
std::ifstream ifs("/proc/stat");
ifs >> std::noskipws;
Cpu_parser< boost::spirit::istream_iterator > cpu_parser;
std::cout << phrase_parse(
boost::spirit::istream_iterator(ifs),
boost::spirit::istream_iterator(),
cpu_parser % qi::eol,
ascii::blank,
cpus) << std::endl;
}
return 0;
}
The commented out line with all of the individual uint_s works fine, but I'd like to know what I'm doing wrong with repeat.
I can also get repeat to work if I replace the Cpu struct with a vector of unsigned ints.