LCOV - code coverage report
Current view: top level - core/include/mcrl2/core - parse.h (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 63 81 77.8 %
Date: 2020-02-13 00:44:47 Functions: 96 107 89.7 %
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/parse.h
      10             : ///
      11             : /// \brief Parse mCRL2 specifications and expressions.
      12             : 
      13             : #ifndef MCRL2_CORE_PARSE_H
      14             : #define MCRL2_CORE_PARSE_H
      15             : 
      16             : #include "mcrl2/atermpp/aterm_io.h"
      17             : #include "mcrl2/core/detail/dparser_functions.h"
      18             : #include "mcrl2/core/identifier_string.h"
      19             : 
      20             : struct D_ParserTables; // prototype
      21             : 
      22             : extern "C"
      23             : {
      24             :   extern D_ParserTables parser_tables_mcrl2;
      25             :   extern D_ParserTables parser_tables_fsm;
      26             :   extern D_ParserTables parser_tables_dot;
      27             : }
      28             : 
      29             : namespace mcrl2
      30             : {
      31             : namespace core
      32             : {
      33             : 
      34           4 : class parse_node_exception : public mcrl2::runtime_error
      35             : {
      36             : protected:
      37           4 :   static std::string get_error_message(const parse_node& node, const std::string& user_message)
      38             :   {
      39             :     try
      40             :     {
      41           4 :       return node.add_context(user_message);
      42             :     }
      43           0 :     catch (...)
      44             :     {
      45           0 :       return user_message;
      46             :     }
      47             :   }
      48             : 
      49           0 :   parse_node_exception(const std::string& message)
      50           0 :     : mcrl2::runtime_error(message)
      51           0 :   { }
      52             : 
      53             : public:
      54           4 :   parse_node_exception(const parse_node& node, const std::string& message)
      55           4 :     : mcrl2::runtime_error(get_error_message(node, message))
      56           4 :   { }
      57             : };
      58             : 
      59           0 : class parse_node_unexpected_exception : public parse_node_exception
      60             : {
      61             : private:
      62           0 :   static std::string get_error_message(const parser& p, const parse_node& node)
      63             :   {
      64           0 :     std::string inherited = parse_node_exception::get_error_message(node, "unexpected parse node!");
      65             :     try
      66             :     {
      67           0 :       std::ostringstream out;
      68           0 :       out << inherited << std::endl;
      69           0 :       p.print_node(out, node);
      70           0 :       return out.str();
      71             :     }
      72           0 :     catch (...)
      73             :     {
      74           0 :       return inherited;
      75             :     }
      76             :   }
      77             : public:
      78           0 :   parse_node_unexpected_exception(const parser& p, const parse_node& node)
      79           0 :     : parse_node_exception(get_error_message(p, node))
      80           0 :   { }
      81             : };
      82             : 
      83             : struct parser_actions
      84             : {
      85             :   const parser& m_parser;
      86             : 
      87        2889 :   parser_actions(const parser& parser_)
      88        2889 :     : m_parser(parser_)
      89        2889 :   {}
      90             : 
      91             :   // starts a traversal in node, and calls the function f to each subnode of the given type
      92             :   template <typename Function>
      93      193413 :   void traverse(const parse_node& node, const Function& f) const
      94             :   {
      95      193413 :     if (!node)
      96             :     {
      97           0 :       return;
      98             :     }
      99      193413 :     if (!f(node))
     100             :     {
     101      308297 :       for (int i = 0; i < node.child_count(); i++)
     102             :       {
     103      159817 :         traverse(node.child(i), f);
     104             :       }
     105             :     }
     106             :   }
     107             : 
     108             :   // callback function that applies a function to nodes of a given type
     109             :   template <typename Function>
     110             :   struct visitor
     111             :   {
     112             :     const parser_table& table;
     113             :     const std::string& type;
     114             :     const Function& f;
     115             : 
     116           4 :     visitor(const parser_table& table_, const std::string& type_, const Function& f_)
     117             :       : table(table_),
     118             :         type(type_),
     119           4 :         f(f_)
     120           4 :     {}
     121             : 
     122         136 :     bool operator()(const parse_node& node) const
     123             :     {
     124         136 :       if (table.symbol_name(node) == type)
     125             :       {
     126         128 :         f(node);
     127         128 :         return true;
     128             :       }
     129           8 :       return false;
     130             :     }
     131             :   };
     132             : 
     133             :   template <typename Function>
     134           4 :   visitor<Function> make_visitor(const parser_table& table, const std::string& type, const Function& f) const
     135             :   {
     136           4 :     return visitor<Function>(table, type, f);
     137             :   }
     138             : 
     139             :   // callback function that applies a function to a node, and adds the result to a container
     140             :   template <typename Container, typename Function>
     141             :   struct collector
     142             :   {
     143             :     const parser_table& table;
     144             :     const std::string& type;
     145             :     Container& container;
     146             :     const Function& f;
     147             : 
     148       23920 :     collector(const parser_table& table_, const std::string& type_, Container& container_, const Function& f_)
     149             :       : table(table_),
     150             :         type(type_),
     151             :         container(container_),
     152       23920 :         f(f_)
     153       23920 :     {}
     154             : 
     155      105231 :     bool operator()(const parse_node& node) const
     156             :     {
     157      105231 :       if (table.symbol_name(node) == type)
     158             :       {
     159       30455 :         container.push_back(f(node));
     160       30455 :         return true;
     161             :       }
     162       74776 :       return false;
     163             :     }
     164             :   };
     165             : 
     166             :   template <typename Container, typename Function>
     167       23920 :   collector<Container, Function> make_collector(const parser_table& table, const std::string& type, Container& container, const Function& f) const
     168             :   {
     169       23920 :     return collector<Container, Function>(table, type, container, f);
     170             :   }
     171             : 
     172             :   // callback function that applies a function to a node, and adds the result to a set container
     173             :   template <typename SetContainer, typename Function>
     174             :   struct set_collector
     175             :   {
     176             :     const parser_table& table;
     177             :     const std::string& type;
     178             :     SetContainer& container;
     179             :     const Function& f;
     180             : 
     181         128 :     set_collector(const parser_table& table_, const std::string& type_, SetContainer& container_, const Function& f_)
     182             :       : table(table_),
     183             :         type(type_),
     184             :         container(container_),
     185         128 :         f(f_)
     186         128 :     {}
     187             : 
     188         672 :     bool operator()(const parse_node& node) const
     189             :     {
     190         672 :       if (table.symbol_name(node) == type)
     191             :       {
     192         224 :         container.insert(f(node));
     193         224 :         return true;
     194             :       }
     195         448 :       return false;
     196             :     }
     197             :   };
     198             : 
     199             :   template <typename SetContainer, typename Function>
     200         128 :   set_collector<SetContainer, Function> make_set_collector(const parser_table& table, const std::string& type, SetContainer& container, const Function& f) const
     201             :   {
     202         128 :     return set_collector<SetContainer, Function>(table, type, container, f);
     203             :   }
     204             : 
     205      606973 :   std::string symbol_name(const parse_node& node) const
     206             :   {
     207      606973 :     return m_parser.symbol_table().symbol_name(node.symbol());
     208             :   }
     209             : };
     210             : 
     211             : struct default_parser_actions: public parser_actions
     212             : {
     213        2889 :   default_parser_actions(const parser& parser_)
     214        2889 :     : parser_actions(parser_)
     215        2889 :   {}
     216             : 
     217             :   template <typename T, typename Function>
     218       22638 :   atermpp::term_list<T> parse_list(const parse_node& node, const std::string& type, const Function& f) const
     219             :   {
     220       45276 :     std::vector<T> result;
     221       22638 :     traverse(node, make_collector(m_parser.symbol_table(), type, result, f));
     222       45276 :     return atermpp::term_list<T>(result.begin(), result.end());
     223             :   }
     224             : 
     225             :   template <typename T, typename Function>
     226        1282 :   std::vector<T> parse_vector(const parse_node& node, const std::string& type, const Function& f) const
     227             :   {
     228        1282 :     std::vector<T> result;
     229        1282 :     traverse(node, make_collector(m_parser.symbol_table(), type, result, f));
     230        1282 :     return result;
     231             :   }
     232             : 
     233       48820 :   core::identifier_string parse_Id(const parse_node& node) const
     234             :   {
     235       48820 :     return core::identifier_string(node.string());
     236             :   }
     237             : 
     238        5174 :   core::identifier_string parse_Number(const parse_node& node) const
     239             :   {
     240        5174 :     return core::identifier_string(node.string());
     241             :   }
     242             : 
     243       11039 :   core::identifier_string_list parse_IdList(const parse_node& node) const
     244             :   {
     245             : #ifdef _MSC_VER
     246             :     return parse_list<core::identifier_string>(node, "Id", [&](const core::parse_node& node) { return parse_Id(node); });
     247             : #else
     248       11039 :     return parse_list<core::identifier_string>(node, "Id", std::bind(&default_parser_actions::parse_Id, this, std::placeholders::_1));
     249             : #endif
     250             :   }
     251             : };
     252             : 
     253             : template <typename T>
     254             : void print_aterm(const T&)
     255             : {
     256             : }
     257             : 
     258             : template<>
     259             : inline
     260             : void print_aterm(const atermpp::aterm_appl& x)
     261             : {
     262             :   std::clog << "aterm: " << x << std::endl;
     263             : }
     264             : 
     265             : /// \brief Parse an identifier.
     266             : inline
     267             : identifier_string parse_identifier(const std::string& text)
     268             : {
     269             :   core::parser p(parser_tables_mcrl2, core::detail::ambiguity_fn, core::detail::syntax_error_fn);
     270             :   unsigned int start_symbol_index = p.start_symbol_index("Id");
     271             :   bool partial_parses = false;
     272             :   core::parse_node node = p.parse(text, start_symbol_index, partial_parses);
     273             :   identifier_string result = default_parser_actions(p).parse_Id(node);
     274             :   return result;
     275             : }
     276             : 
     277             : inline
     278             : bool is_user_identifier(std::string const& s)
     279             : {
     280             :   try
     281             :   {
     282             :     parse_identifier(s);
     283             :   }
     284             :   catch (...)
     285             :   {
     286             :     return false;
     287             :   }
     288             :   return true;
     289             : }
     290             : 
     291             : } // namespace core
     292             : } // namespace mcrl2
     293             : 
     294             : #endif // MCRL2_CORE_PARSE_H

Generated by: LCOV version 1.13