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