Advertisement
dan-masek

Log Line Parser

Mar 19th, 2017
371
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.72 KB | None | 0 0
  1. #define BOOST_SPIRIT_DEBUG 1
  2. // ============================================================================
  3. #include <boost/spirit/include/qi.hpp>
  4. #include <boost/fusion/include/adapt_struct.hpp>
  5. // ============================================================================
  6. namespace qi = boost::spirit::qi;
  7. // ============================================================================
  8. struct log_entry_t
  9. {
  10.     std::string element_0;
  11.     std::string element_1;
  12.     int32_t element_2;
  13.     int32_t element_3;
  14.     int32_t element_4;
  15.     int32_t element_5;
  16.     std::string element_6;
  17.     std::string element_7;
  18.     std::string element_8;
  19. };
  20. // ============================================================================
  21. BOOST_FUSION_ADAPT_STRUCT(
  22.     log_entry_t
  23.     , (std::string, element_0)
  24.     , (std::string, element_1)
  25.     , (int32_t, element_2)
  26.     , (int32_t, element_3)
  27.     , (int32_t, element_4)
  28.     , (int32_t, element_5)
  29.     , (std::string, element_6)
  30.     , (std::string, element_7)
  31.     , (std::string, element_8)
  32. )
  33. // ============================================================================
  34. // Sample log entry:
  35. // ^+ line-17532.dyn.kponet.fi      2   7   377     1   +1503us[+9103us] +/-   55ms
  36. //
  37. template <typename Iterator>
  38. struct log_line_parser
  39.     : qi::grammar<Iterator, log_entry_t(), boost::spirit::ascii::space_type>
  40. {
  41.     typedef boost::spirit::ascii::space_type skipper_t;
  42.  
  43.     log_line_parser()
  44.         : log_line_parser::base_type(log_line)
  45.     {
  46.         element_0 %= qi::string("^+");
  47.         element_1 %= +qi::char_("-.a-zA-Z0-9");
  48.         element_2 %= qi::int_;
  49.         element_3 %= qi::int_;
  50.         element_4 %= qi::int_;
  51.         element_5 %= qi::int_;
  52.         element_6 %= qi::raw[qi::char_('+') >> qi::int_ >> time_unit];
  53.         element_7 %= qi::raw[qi::char_('+') >> qi::int_ >> time_unit];
  54.         element_8 %= qi::raw[qi::int_ >> time_unit];
  55.  
  56.         time_unit %= -qi::char_("nmu") >> qi::char_('s');
  57.  
  58.         log_line
  59.             %=  element_0
  60.             >>  element_1
  61.             >>  element_2
  62.             >>  element_3
  63.             >>  element_4
  64.             >>  element_5
  65.             >>  element_6
  66.             >>  qi::lit('[') >> element_7 >> qi::lit(']')
  67.             >>  qi::lit("+/-")
  68.             >>  element_8
  69.             ;
  70.  
  71.         init_debug();
  72.     }
  73.  
  74.     void init_debug()
  75.     {
  76.         BOOST_SPIRIT_DEBUG_NODE(element_0);
  77.         BOOST_SPIRIT_DEBUG_NODE(element_1);
  78.         BOOST_SPIRIT_DEBUG_NODE(element_2);
  79.         BOOST_SPIRIT_DEBUG_NODE(element_3);
  80.         BOOST_SPIRIT_DEBUG_NODE(element_4);
  81.         BOOST_SPIRIT_DEBUG_NODE(element_5);
  82.         BOOST_SPIRIT_DEBUG_NODE(element_6);
  83.         BOOST_SPIRIT_DEBUG_NODE(element_7);
  84.         BOOST_SPIRIT_DEBUG_NODE(element_8);
  85.  
  86.         BOOST_SPIRIT_DEBUG_NODE(time_unit);
  87.  
  88.         BOOST_SPIRIT_DEBUG_NODE(log_line);
  89.     }
  90.  
  91. private:
  92.     qi::rule<Iterator, std::string()> element_0;
  93.     qi::rule<Iterator, std::string()> element_1;
  94.     qi::rule<Iterator, int32_t()> element_2;
  95.     qi::rule<Iterator, int32_t()> element_3;
  96.     qi::rule<Iterator, int32_t()> element_4;
  97.     qi::rule<Iterator, int32_t()> element_5;
  98.     qi::rule<Iterator, std::string()> element_6;
  99.     qi::rule<Iterator, std::string()> element_7;
  100.     qi::rule<Iterator, std::string()> element_8;
  101.  
  102.     qi::rule<Iterator, std::string()> time_unit;
  103.  
  104.     qi::rule<Iterator, log_entry_t(), skipper_t> log_line;
  105. };
  106. // ============================================================================
  107. int main()
  108. {
  109.     std::string log("^+ line-17532.dyn.kponet.fi      2   7   377     1   +1503us[+9103us] +/-   55ms");
  110.  
  111.  
  112.     std::string::const_iterator iter(log.begin());
  113.     std::string::const_iterator end(log.end());
  114.  
  115.     log_line_parser<std::string::const_iterator> g;
  116.  
  117.     log_entry_t entry;
  118.  
  119.     using boost::spirit::ascii::space;
  120.     bool r(qi::phrase_parse(iter, end, g, space, entry));
  121.  
  122.     std::cout << "-------------------------\n";
  123.  
  124.     if (r && (iter == end)) {
  125.         std::cout << "Parsing succeeded\n";
  126.         std::cout << entry.element_0 << "\n"
  127.             << entry.element_1 << "\n"
  128.             << entry.element_2 << "\n"
  129.             << entry.element_3 << "\n"
  130.             << entry.element_4 << "\n"
  131.             << entry.element_5 << "\n"
  132.             << entry.element_6 << "\n"
  133.             << entry.element_7 << "\n"
  134.             << entry.element_8 << "\n";
  135.         return 0;
  136.     } else {
  137.         std::string::const_iterator some = iter + 30;
  138.         std::string context(iter, (some > end) ? end : some);
  139.         std::cout << "Parsing failed\n";
  140.         std::cout << "stopped at: \": " << context << "...\"\n";
  141.         return 1;
  142.     }
  143. }
  144. // ============================================================================
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement