Coverage Report

Created: 2025-06-13 06:46

/src/Fast-DDS/thirdparty/taocpp-pegtl/pegtl/analysis/analyze_cycles.hpp
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) 2014-2020 Dr. Colin Hirsch and Daniel Frey
2
// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/
3
4
#ifndef TAO_PEGTL_ANALYSIS_ANALYZE_CYCLES_HPP
5
#define TAO_PEGTL_ANALYSIS_ANALYZE_CYCLES_HPP
6
7
#include <cassert>
8
9
#include <map>
10
#include <set>
11
#include <stdexcept>
12
13
#include <iostream>
14
#include <utility>
15
16
#include "../config.hpp"
17
18
#include "grammar_info.hpp"
19
#include "insert_guard.hpp"
20
21
namespace tao
22
{
23
   namespace TAO_PEGTL_NAMESPACE
24
   {
25
      namespace analysis
26
      {
27
         class analyze_cycles_impl
28
         {
29
         protected:
30
            explicit analyze_cycles_impl( const bool verbose ) noexcept
31
0
               : m_verbose( verbose ),
32
0
                 m_problems( 0 )
33
0
            {
34
0
            }
35
36
            const bool m_verbose;
37
            unsigned m_problems;
38
            grammar_info m_info;
39
            std::set< std::string > m_stack;
40
            std::map< std::string, bool > m_cache;
41
            std::map< std::string, bool > m_results;
42
43
            std::map< std::string, rule_info >::const_iterator find( const std::string& name ) const noexcept
44
0
            {
45
0
               const auto iter = m_info.map.find( name );
46
0
               assert( iter != m_info.map.end() );
47
0
               return iter;
48
0
            }
49
50
            bool work( const std::map< std::string, rule_info >::const_iterator& start, const bool accum )
51
0
            {
52
0
               const auto j = m_cache.find( start->first );
53
54
0
               if( j != m_cache.end() ) {
55
0
                  return j->second;
56
0
               }
57
0
               if( const auto g = make_insert_guard( m_stack, start->first ) ) {
58
0
                  switch( start->second.type ) {
59
0
                     case rule_type::any: {
60
0
                        bool a = false;
61
0
                        for( const auto& r : start->second.rules ) {
62
0
                           a = a || work( find( r ), accum || a );
63
0
                        }
64
0
                        return m_cache[ start->first ] = true;
65
0
                     }
66
0
                     case rule_type::opt: {
67
0
                        bool a = false;
68
0
                        for( const auto& r : start->second.rules ) {
69
0
                           a = a || work( find( r ), accum || a );
70
0
                        }
71
0
                        return m_cache[ start->first ] = false;
72
0
                     }
73
0
                     case rule_type::seq: {
74
0
                        bool a = false;
75
0
                        for( const auto& r : start->second.rules ) {
76
0
                           a = a || work( find( r ), accum || a );
77
0
                        }
78
0
                        return m_cache[ start->first ] = a;
79
0
                     }
80
0
                     case rule_type::sor: {
81
0
                        bool a = true;
82
0
                        for( const auto& r : start->second.rules ) {
83
0
                           a = a && work( find( r ), accum );
84
0
                        }
85
0
                        return m_cache[ start->first ] = a;
86
0
                     }
87
0
                  }
88
0
                  throw std::logic_error( "code should be unreachable: invalid rule_type value" );  // NOLINT, LCOV_EXCL_LINE
89
0
               }
90
0
               if( !accum ) {
91
0
                  ++m_problems;
92
0
                  if( m_verbose ) {
93
0
                     std::cout << "problem: cycle without progress detected at rule class " << start->first << std::endl;  // LCOV_EXCL_LINE
94
0
                  }
95
0
               }
96
0
               return m_cache[ start->first ] = accum;
97
0
            }
98
         };
99
100
         template< typename Grammar >
101
         class analyze_cycles
102
            : private analyze_cycles_impl
103
         {
104
         public:
105
            explicit analyze_cycles( const bool verbose )
106
0
               : analyze_cycles_impl( verbose )
107
0
            {
108
0
               Grammar::analyze_t::template insert< Grammar >( m_info );
109
0
            }
110
111
            std::size_t problems()
112
0
            {
113
0
               for( auto i = m_info.map.begin(); i != m_info.map.end(); ++i ) {
114
0
                  m_results[ i->first ] = work( i, false );
115
0
                  m_cache.clear();
116
0
               }
117
0
               return m_problems;
118
0
            }
119
120
            template< typename Rule >
121
            bool consumes() const noexcept
122
            {
123
               const auto i = m_results.find( internal::demangle< Rule >() );
124
               assert( i != m_results.end() );
125
               return i->second;
126
            }
127
         };
128
129
      }  // namespace analysis
130
131
   }  // namespace TAO_PEGTL_NAMESPACE
132
133
}  // namespace tao
134
135
#endif