LCOV - code coverage report
Current view: top level - core/include/mcrl2/core - parser_utility.h (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 4 4 100.0 %
Date: 2024-04-13 03:38:08 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Author(s): Wieger Wesselink
       2             : // Copyright: see the accompanying file COPYING or copy at
       3             : // https://github.com/mCRL2org/mCRL2/blob/master/COPYING
       4             : //
       5             : // Distributed under the Boost Software License, Version 1.0.
       6             : // (See accompanying file LICENSE_1_0.txt or copy at
       7             : // http://www.boost.org/LICENSE_1_0.txt)
       8             : //
       9             : /// \file mcrl2/core/parser_utility.h
      10             : /// \brief add your file description here.
      11             : 
      12             : #ifndef MCRL2_CORE_PARSER_UTILITY_H
      13             : #define MCRL2_CORE_PARSER_UTILITY_H
      14             : 
      15             : #include "mcrl2/core/parse.h"
      16             : 
      17             : namespace mcrl2 {
      18             : 
      19             : namespace core {
      20             : 
      21             : namespace detail {
      22             : 
      23             : /// \brief Calls the function f on each node in the parse tree with x as root
      24             : template <typename Function>
      25             : void foreach_parse_node(const parse_node& x, Function f)
      26             : {
      27             :   if (x)
      28             :   {
      29             :     f(x);
      30             :     for (int i = 0; i < x.child_count(); i++)
      31             :     {
      32             :       foreach_parse_node(x.child(i), f);
      33             :     }
      34             :   }
      35             : }
      36             : 
      37             : /// \brief Checks if a node is the binary operation op
      38             : struct is_binary_operator_node
      39             : {
      40             :   const parser_table& table;
      41             :   std::string op;
      42             : 
      43             :   is_binary_operator_node(const parser_table& table_, const std::string& op_)
      44             :     : table(table_),
      45             :       op(op_)
      46             :   {}
      47             : 
      48             :   bool operator()(const parse_node& x)
      49             :   {
      50             :     if (!x)
      51             :     {
      52             :       return false;
      53             :     }
      54             :     bool result = true;
      55             :     if (x.child_count() != 3)
      56             :     {
      57             :       result = false;
      58             :     }
      59             :     else
      60             :     {
      61             :       if (table.symbol_name(x.child(1).symbol()) != op)
      62             :       {
      63             :         result = false;
      64             :       }
      65             :     }
      66             :     return result;
      67             :   }
      68             : };
      69             : 
      70             : /// \brief Checks if a node is the binary operation '&&'
      71             : struct is_and_node: public is_binary_operator_node
      72             : {
      73             :   is_and_node(const parser_table& table_)
      74             :     : is_binary_operator_node(table_, "&&")
      75             :   {}
      76             : };
      77             : 
      78             : /// \brief Checks if a node is the binary operation '||'
      79             : struct is_or_node: public is_binary_operator_node
      80             : {
      81             :   is_or_node(const parser_table& table_)
      82             :     : is_binary_operator_node(table_, "||")
      83             :   {}
      84             : };
      85             : 
      86             : /// \brief Checks if a node is the merge operation '||'
      87             : struct is_merge_node: public is_binary_operator_node
      88             : {
      89             :   is_merge_node(const parser_table& table_)
      90             :     : is_binary_operator_node(table_, "||")
      91             :   {}
      92             : };
      93             : 
      94             : /// \brief Checks if a node is the left merge operation '||_'
      95             : struct is_left_merge_node: public is_binary_operator_node
      96             : {
      97             :   is_left_merge_node(const parser_table& table_)
      98             :     : is_binary_operator_node(table_, "||_")
      99             :   {}
     100             : };
     101             : 
     102             : /// \brief Checks if a node is of type 'x && (y || z)'
     103             : struct is_and_or_node
     104             : {
     105             :   const parser_table& table;
     106             : 
     107             :   is_and_or_node(const parser_table& table_)
     108             :     : table(table_)
     109             :   {}
     110             : 
     111             :   bool operator()(const parse_node& x)
     112             :   {
     113             :     bool result = true;
     114             :     if (!is_and_node(table)(x))
     115             :     {
     116             :       result = false;
     117             :     }
     118             :     else
     119             :     {
     120             :       // check if the types match
     121             :       parse_node left = x.child(0);
     122             :       parse_node right = x.child(2);
     123             :       if (x.symbol() != left.symbol())
     124             :       {
     125             :         result = false;
     126             :       }
     127             :       if (x.symbol() != right.symbol())
     128             :       {
     129             :         result = false;
     130             :       }
     131             :       if (!is_or_node(table)(right))
     132             :       {
     133             :         result = false;
     134             :       }
     135             :     }
     136             :     return result;
     137             :   }
     138             : };
     139             : 
     140             : /// \brief Checks if a node is of type 'x ||_ (y || z)'
     141             : struct is_left_merge_merge
     142             : {
     143             :   const parser_table& table;
     144             : 
     145             :   is_left_merge_merge(const parser_table& table_)
     146             :     : table(table_)
     147             :   {}
     148             : 
     149             :   bool operator()(const parse_node& x)
     150             :   {
     151             :     bool result = true;
     152             :     if (!is_left_merge_node(table)(x))
     153             :     {
     154             :       result = false;
     155             :     }
     156             :     else
     157             :     {
     158             :       // check if the types match
     159             :       parse_node left = x.child(0);
     160             :       parse_node right = x.child(2);
     161             :       if (x.symbol() != left.symbol())
     162             :       {
     163             :         result = false;
     164             :       }
     165             :       if (x.symbol() != right.symbol())
     166             :       {
     167             :         result = false;
     168             :       }
     169             :       if (!is_merge_node(table)(right))
     170             :       {
     171             :         result = false;
     172             :       }
     173             :     }
     174             :     return result;
     175             :   }
     176             : };
     177             : 
     178             : struct find_and_or
     179             : {
     180             :   const parser_table& table;
     181             : 
     182             :   find_and_or(const parser_table& table_)
     183             :     : table(table_)
     184             :   {}
     185             : 
     186             :   void operator()(const parse_node& x)
     187             :   {
     188             :     if (is_and_or_node(table)(x))
     189             :     {
     190             :       std::cout << "Warning: the expression of the form 'x && y || z' on location " << x.line() << ":" << x.column() << " may be parsed differently than before" << std::endl;
     191             :     }
     192             :   }
     193             : };
     194             : 
     195             : struct find_left_merge_merge
     196             : {
     197             :   const parser_table& table;
     198             : 
     199             :   find_left_merge_merge(const parser_table& table_)
     200             :     : table(table_)
     201             :   {}
     202             : 
     203             :   void operator()(const parse_node& x)
     204             :   {
     205             :     if (is_left_merge_merge(table)(x))
     206             :     {
     207             :       std::cout << "Warning: the expression of the form 'x ||_ y || z' on location " << x.line() << ":" << x.column() << " may be parsed differently than before" << std::endl;
     208             :     }
     209             :   }
     210             : };
     211             : 
     212             : } // namespace detail
     213             : 
     214             : /// \brief Prints a warning for each occurrence of 'x && y || z' in the parse tree.
     215             : inline
     216        2698 : void warn_and_or(const parse_node& /* node */)
     217             : {
     218             :   // core::detail::foreach_parse_node(node, core::detail::find_and_or(parser_tables_mcrl2));
     219        2698 : }
     220             : 
     221             : /// \brief Prints a warning for each occurrence of 'x ||_ y || z' in the parse tree.
     222             : inline
     223        1160 : void warn_left_merge_merge(const parse_node& /* node */)
     224             : {
     225             :   // core::detail::foreach_parse_node(node, core::detail::find_left_merge_merge(parser_tables_mcrl2));
     226        1160 : }
     227             : 
     228             : } // namespace core
     229             : 
     230             : } // namespace mcrl2
     231             : 
     232             : #endif // MCRL2_CORE_PARSER_UTILITY_H

Generated by: LCOV version 1.14