1 // Copyright (c) 2007-2017 Hartmut Kaiser 2 // Copyright (c) 2011 Bryce Lelbach 3 // 4 // Distributed under the Boost Software License, Version 1.0. (See accompanying 5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 7 #include <hpx/config.hpp> 8 #include <hpx/performance_counters/counter_parser.hpp> 9 #include <hpx/performance_counters/counters.hpp> 10 11 #define BOOST_SPIRIT_USE_PHOENIX_V3 12 #include <boost/fusion/include/adapt_struct.hpp> 13 #include <boost/spirit/include/qi_auxiliary.hpp> 14 #include <boost/spirit/include/qi_char.hpp> 15 #include <boost/spirit/include/qi_directive.hpp> 16 #include <boost/spirit/include/qi_nonterminal.hpp> 17 #include <boost/spirit/include/qi_numeric.hpp> 18 #include <boost/spirit/include/qi_operator.hpp> 19 #include <boost/spirit/include/qi_parse.hpp> 20 #include <boost/spirit/include/qi_string.hpp> 21 22 #include <string> 23 24 BOOST_FUSION_ADAPT_STRUCT( 25 hpx::performance_counters::instance_name, 26 (std::string, name_) 27 (std::string, index_) 28 (bool, basename_) 29 ) 30 31 BOOST_FUSION_ADAPT_STRUCT( 32 hpx::performance_counters::instance_elements, 33 (hpx::performance_counters::instance_name, parent_) 34 (hpx::performance_counters::instance_name, child_) 35 (hpx::performance_counters::instance_name, subchild_) 36 ) 37 38 BOOST_FUSION_ADAPT_STRUCT( 39 hpx::performance_counters::path_elements, 40 (std::string, object_) 41 (hpx::performance_counters::instance_elements, instance_) 42 (std::string, counter_) 43 (std::string, parameters_) 44 ) 45 46 namespace 47 { 48 /// 49 /// /objectname{parentinstancename#parentindex/instancename#instanceindex} 50 /// /countername#parameters 51 /// /objectname{parentinstancename#*/instancename#*}/countername#parameters 52 /// /objectname{/basecounter}/countername,parameters 53 /// 54 namespace qi = boost::spirit::qi; 55 56 template <typename Iterator> 57 struct path_parser 58 : qi::grammar<Iterator, hpx::performance_counters::path_elements()> 59 { path_parser__anonc109346b0111::path_parser60 path_parser() 61 : path_parser::base_type(start) 62 { 63 start = -qi::lit(hpx::performance_counters::counter_prefix) 64 >> '/' >> +~qi::char_("/{#@") >> -instance 65 >> -('/' >> +~qi::char_("#}@")) >> -('@' >> +qi::char_); 66 instance = 67 '{' >> parent >> -('/' >> child) >> -('/' >> subchild) >> '}' 68 ; 69 parent = 70 &qi::lit('/') >> qi::raw[start] >> qi::attr(-1) >> qi::attr(true) 71 // base counter 72 | +~qi::char_("#/}") 73 >> ( '#' >> raw_uint // counter parent-instance name 74 | -qi::string("#*") // counter parent-instance skeleton name 75 ) 76 >> qi::attr(false) 77 ; 78 child = 79 +~qi::char_("#/}") 80 >> ( qi::char_('#') >> +~qi::char_("/}") // counter instance name 81 | -qi::string("#*") // counter instance skeleton name 82 ) 83 >> qi::attr(false) 84 ; 85 subchild = 86 +~qi::char_("#}") 87 >> ( '#' >> raw_uint // counter (sub-)instance name 88 | -qi::string("#*") // counter (sub-)instance skeleton name 89 ) 90 >> qi::attr(false) 91 ; 92 raw_uint = qi::raw[qi::uint_]; 93 } 94 95 qi::rule<Iterator, hpx::performance_counters::path_elements()> start; 96 qi::rule<Iterator, hpx::performance_counters::instance_elements()> instance; 97 qi::rule<Iterator, hpx::performance_counters::instance_name()> parent; 98 qi::rule<Iterator, hpx::performance_counters::instance_name()> child; 99 qi::rule<Iterator, hpx::performance_counters::instance_name()> subchild; 100 qi::rule<Iterator, std::string()> raw_uint; 101 }; 102 } 103 104 namespace hpx { namespace performance_counters 105 { parse_counter_name(std::string const & name,path_elements & elements)106 bool parse_counter_name(std::string const& name, path_elements& elements) 107 { 108 path_parser<std::string::const_iterator> p; 109 110 // parse the full name 111 std::string::const_iterator begin = name.begin(); 112 return qi::parse(begin, name.end(), p, elements) && begin == name.end(); 113 } 114 }} 115