LCOV - code coverage report
Current view: top level - process/include/mcrl2/process/detail - alphabet_parse.h (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 83 95 87.4 %
Date: 2024-04-26 03:18:02 Functions: 14 16 87.5 %
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/process/detail/alphabet_parse.h
      10             : /// \brief add your file description here.
      11             : 
      12             : #ifndef MCRL2_PROCESS_DETAIL_ALPHABET_PARSE_H
      13             : #define MCRL2_PROCESS_DETAIL_ALPHABET_PARSE_H
      14             : 
      15             : #include "mcrl2/process/multi_action_name.h"
      16             : #include "mcrl2/process/parse.h"
      17             : 
      18             : namespace mcrl2 {
      19             : 
      20             : namespace process {
      21             : 
      22             : namespace detail {
      23             : 
      24             : // Removes surrounding braces from a string.
      25             : inline
      26          51 : std::string remove_braces(const std::string& text)
      27             : {
      28          51 :   std::string s = utilities::trim_copy(text);
      29          51 :   if (s.size() < 2 || s.front() != '{' || s.back() != '}')
      30             :   {
      31           0 :     throw mcrl2::runtime_error("Expected braces around string: " + text);
      32             :   }
      33          51 :   s = s.substr(1, s.size() - 2);
      34         102 :   return utilities::trim_copy(s);
      35          51 : }
      36             : 
      37             : // Removes a trailing @ symbol from a string, if it exists.
      38             : // Returns the resulting string, and a boolean indicating if an @ symbol was removed.
      39             : inline
      40          34 : std::pair<std::string, bool> remove_trailing_at_symbol(const std::string& text)
      41             : {
      42          34 :   std::string s = utilities::trim_copy(text);
      43          34 :   bool found_at_symbol = false;
      44          34 :   if (!s.empty() && s.back() == '@')
      45             :   {
      46           6 :     found_at_symbol = true;
      47           6 :     s.erase(s.size() - 1);
      48             :   }
      49          68 :   return { s, found_at_symbol };
      50          34 : }
      51             : 
      52             : // Returns the elements of a comma separated list inside braces.
      53             : // For example "{ s1, s2, s3 }" -> [s1, s2, s3]
      54             : inline
      55          51 : std::vector<std::string> set_elements(const std::string& text)
      56             : {
      57          51 :   std::string s = remove_braces(text);
      58         102 :   return utilities::regex_split(s, "\\s*,\\s*");
      59          51 : }
      60             : 
      61             : // Returns the left and right hand sides of strings separated by "->".
      62             : // For example "s1 -> s2" -> [s1, s2]
      63             : inline
      64          15 : std::pair<std::string, std::string> split_arrow(const std::string& text)
      65             : {
      66          15 :   std::string s = utilities::trim_copy(text);
      67          30 :   std::vector<std::string> w = utilities::regex_split(s, "\\s*->\\s*");
      68          15 :   if (w.size() != 2)
      69             :   {
      70           0 :     throw mcrl2::runtime_error("Expected a string of the shape lhs -> rhs: " + text);
      71             :   }
      72          30 :   return { w[0], w[1] };
      73          15 : }
      74             : 
      75             : // Returns the elements of a bar separated list.
      76             : // For example "s1 | s2 | s3" -> [s1, s2, s3]
      77             : inline
      78          10 : std::vector<std::string> split_bar(const std::string& text)
      79             : {
      80          10 :   std::string s = utilities::trim_copy(text);
      81          20 :   return utilities::regex_split(s, R"(\s*\|\s*)");
      82          10 : }
      83             : 
      84             : // Splits a word into characters.
      85             : inline
      86          60 : std::vector<std::string> split_characters(const std::string& text)
      87             : {
      88          60 :   std::string s = utilities::trim_copy(text);
      89          60 :   std::vector<std::string> result;
      90         182 :   for (char & i : s)
      91             :   {
      92         122 :     result.emplace_back(1, i);
      93             :   }
      94         120 :   return result;
      95          60 : }
      96             : 
      97             : // Converts a vector of strings into an identifier_string_list.
      98             : inline
      99          13 : core::identifier_string_list make_identifier_string_list(const std::vector<std::string>& words)
     100             : {
     101          13 :   std::vector<core::identifier_string> ids;
     102          33 :   for (const std::string& word: words)
     103             :   {
     104          20 :     ids.emplace_back(word);
     105             :   }
     106          26 :   return core::identifier_string_list(ids.begin(), ids.end());
     107          13 : }
     108             : 
     109             : // Converts a list of strings into a multi action name.
     110             : inline
     111          60 : multi_action_name make_multi_action(const std::vector<std::string>& words)
     112             : {
     113          60 :   multi_action_name result;
     114         182 :   for (const std::string& word: words)
     115             :   {
     116         122 :     result.insert(core::identifier_string(word));
     117             :   }
     118          60 :   return result;
     119           0 : }
     120             : 
     121             : // Parses a multi action name.
     122             : // Example: "s1 | s2 | s3" -> {s1, s2, s3}.
     123             : inline
     124           0 : multi_action_name parse_multi_action_name(const std::string& text)
     125             : {
     126           0 :   return make_multi_action(split_bar(text));
     127             : }
     128             : 
     129             : // Parses a multi action name set.
     130             : // Example: "{ s1 | s2 | s3, t1 | t2 }" -> {{s1, s2, s3}, {t2, t2}}
     131           0 : multi_action_name_set parse_multi_action_name_set(const std::string& text)
     132             : {
     133           0 :   std::vector<multi_action_name> result;
     134           0 :   for (const std::string& word: set_elements(text))
     135             :   {
     136           0 :     result.push_back(parse_multi_action_name(word));
     137           0 :   }
     138           0 :   return multi_action_name_set(result.begin(), result.end());
     139           0 : }
     140             : 
     141             : // Parses a multi action name. It is assumed that the actions consist of one character.
     142             : // Example: "abc" -> {a, b, c}.
     143             : inline
     144          60 : multi_action_name parse_simple_multi_action_name(const std::string& text)
     145             : {
     146         120 :   return make_multi_action(split_characters(text));
     147             : }
     148             : 
     149             : // Parses a multi action name set, optionally followed by an @ symbol.
     150             : // It is assumed that the actions consist of one character.
     151             : // Example: "{ abc, de }@" -> [{{a, b, c}, {d, e}}, true].
     152             : inline
     153          34 : std::pair<multi_action_name_set, bool> parse_simple_multi_action_name_set(const std::string& text)
     154             : {
     155          34 :   multi_action_name_set result;
     156          34 :   auto p = remove_trailing_at_symbol(text);
     157          34 :   std::string s = p.first;
     158          34 :   bool result_includes_subsets = p.second;
     159             : 
     160          92 :   for (const std::string& word: set_elements(s))
     161             :   {
     162          58 :     result.insert(parse_simple_multi_action_name(word));
     163          34 :   }
     164          68 :   return { result, result_includes_subsets };
     165          34 : }
     166             : 
     167             : inline
     168           2 : action_name_multiset_list parse_allow_set(const std::string& text)
     169             : {
     170           2 :   std::vector<action_name_multiset> result;
     171           8 :   for (const std::string& word: set_elements(text))
     172             :   {
     173           6 :     result.emplace_back(make_identifier_string_list(split_bar(word)));
     174           2 :   }
     175           4 :   return action_name_multiset_list(result.begin(), result.end());
     176           2 : }
     177             : 
     178             : inline
     179           3 : core::identifier_string_list parse_block_set(const std::string& text)
     180             : {
     181           6 :   return make_identifier_string_list(set_elements(text));
     182             : }
     183             : 
     184             : inline
     185           4 : communication_expression_list parse_comm_set(const std::string& text)
     186             : {
     187           4 :   std::vector<communication_expression> result;
     188           8 :   for (const std::string& word: set_elements(text))
     189             :   {
     190           4 :     auto [lhs, rhs] = split_arrow(word);
     191           4 :     result.emplace_back(mcrl2::process::action_name_multiset(make_identifier_string_list(split_bar(lhs))), core::identifier_string(rhs));
     192           8 :   }
     193           8 :   return communication_expression_list(result.begin(), result.end());
     194           4 : }
     195             : 
     196             : inline
     197           8 : rename_expression_list parse_rename_set(const std::string& text)
     198             : {
     199           8 :   std::vector<rename_expression> result;
     200          19 :   for (const std::string& word: set_elements(text))
     201             :   {
     202          11 :     auto [lhs, rhs] = split_arrow(word);
     203          11 :     result.emplace_back(core::identifier_string(lhs), core::identifier_string(rhs));
     204          19 :   }
     205          16 :   return rename_expression_list(result.begin(), result.end());
     206           8 : }
     207             : 
     208             : } // namespace detail
     209             : 
     210             : } // namespace process
     211             : 
     212             : } // namespace mcrl2
     213             : 
     214             : #endif // MCRL2_PROCESS_DETAIL_ALPHABET_PARSE_H

Generated by: LCOV version 1.14