⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 read_graphviz_spirit.hpp

📁 C++的一个好库。。。现在很流行
💻 HPP
📖 第 1 页 / 共 2 页
字号:
    void check_directed() {
      if(!self.graph_.is_directed())
        throw boost::directed_graph_error();
    }
    
    void memoize_node() {
      id_t const& node = node_id.name();
      props_t& node_props = default_node_props; 

      if(nodes.find(node) == nodes.end()) {
        nodes.insert(node);
        self.graph_.do_add_vertex(node);

        node_map.insert(std::make_pair(node,ids_t()));

#ifdef BOOST_GRAPH_DEBUG
        std::cout << "Add new node " << node << std::endl;
#endif // BOOST_GRAPH_DEBUG
        // Set the default properties for this edge
        // RG: Here I  would actually set the properties
        for(props_t::iterator i = node_props.begin();
            i != node_props.end(); ++i) {
          set_node_property(node,i->first,i->second);
        }
        if(subgraph_depth > 0) {
          subgraph.nodes().insert(node);
          // Set the subgraph's default properties as well
          props_t& props = subgraph_node_props[subgraph.name()];
          for(props_t::iterator i = props.begin(); i != props.end(); ++i) {
            set_node_property(node,i->first,i->second);
          }
        }
      } else {
#ifdef BOOST_GRAPH_DEBUG
        std::cout << "See node " << node << std::endl;
#endif // BOOST_GRAPH_DEBUG
      }
    }

    void activate_edge(nodes_t& sources, nodes_t& dests, edges_t& edges,
                       props_t& edge_props) {
      edge_stack_t& edge_stack = data_stmt.edge_stack();
      for(nodes_t::iterator i = sources.begin(); i != sources.end(); ++i) {
        for(nodes_t::iterator j = dests.begin(); j != dests.end(); ++j) {
          // Create the edge and and push onto the edge stack.
#ifdef BOOST_GRAPH_DEBUG
          std::cout << "Edge " << *i << " to " << *j << std::endl;
#endif // BOOST_GRAPH_DEBUG

          edge_t edge = edge_t::new_edge();
          edge_stack.push_back(edge);
          edges.insert(edge);
          edge_map.insert(std::make_pair(edge,ids_t()));

          // Add the real edge.
          self.graph_.do_add_edge(edge, *i, *j);

          // Set the default properties for this edge
          for(props_t::iterator k = edge_props.begin();
              k != edge_props.end(); ++k) {
            set_edge_property(edge,k->first,k->second);
          }
          if(subgraph_depth > 0) {
            subgraph.edges().insert(edge);
            // Set the subgraph's default properties as well
            props_t& props = subgraph_edge_props[subgraph.name()];
            for(props_t::iterator k = props.begin(); k != props.end(); ++k) {
              set_edge_property(edge,k->first,k->second);
            }
          }
        }
      }
    }

    // node_prop - Assign the property for the current active node.
    void node_prop(id_t const& key, id_t const& value) {
      node_t& active_object = data_stmt.active_node();
      set_node_property(active_object, key, value);
    }

    // edge_prop - Assign the property for the current active edges.
    void edge_prop(id_t const& key, id_t const& value) {
      edge_stack_t const& active_edges_ = data_stmt.edge_stack();
      for (edge_stack_t::const_iterator i = active_edges_.begin();
           i != active_edges_.end(); ++i) {
        set_edge_property(*i,key,value);
      }
    }

    // default_graph_prop - Just ignore graph properties.
    void default_graph_prop(id_t const&, id_t const&) { }

    // default_node_prop - declare default properties for any future new nodes
    void default_node_prop(id_t const& key, id_t const& value) {
      nodes_t& nodes_ =
        subgraph_depth == 0 ? nodes : subgraph.nodes();
      props_t& node_props_ =
        subgraph_depth == 0 ?
        default_node_props :
        subgraph_node_props[subgraph.name()];

      // add this to the selected list of default node properties.
      node_props_[key] = value;
      // for each node, set its property to default-constructed value 
      //   if it hasn't been set already.
      // set the dynamic property map value
      for(nodes_t::iterator i = nodes_.begin(); i != nodes_.end(); ++i)
        if(node_map[*i].find(key) == node_map[*i].end()) {
          set_node_property(*i,key,id_t());
        }
    }

    // default_edge_prop - declare default properties for any future new edges
   void default_edge_prop(id_t const& key, id_t const& value) {
      edges_t& edges_ =
        subgraph_depth == 0 ? edges : subgraph.edges();
      props_t& edge_props_ =
        subgraph_depth == 0 ?
        default_edge_props :
        subgraph_edge_props[subgraph.name()];
  
      // add this to the list of default edge properties.
      edge_props_[key] = value;
      // for each edge, set its property to be empty string
      // set the dynamic property map value
      for(edges_t::iterator i = edges_.begin(); i != edges_.end(); ++i)
        if(edge_map[*i].find(key) == edge_map[*i].end())
          set_edge_property(*i,key,id_t());
    }

    // helper function
    void insert_node(nodes_t& nodes, id_t const& name) {
      nodes.insert(name);
    }

    void call_prop_actor(std::string const& lhs, std::string const& rhs) {
      actor_t& actor = attr_list.prop_actor();
      // If first and last characters of the rhs are double-quotes,
      // remove them.
      if (!rhs.empty() && rhs[0] == '"' && rhs[rhs.size() - 1] == '"')
        actor(lhs, rhs.substr(1, rhs.size()-2));
      else
        actor(lhs,rhs);
    }

    void set_node_property(node_t const& node, id_t const& key,
                           id_t const& value) {

      // Add the property key to the "set" table to avoid default overwrite
      node_map[node].insert(key);
      // Set the user's property map
      self.graph_.set_node_property(key, node, value);
#ifdef BOOST_GRAPH_DEBUG
      // Tell the world
      std::cout << node << ": " << key << " = " << value << std::endl;
#endif // BOOST_GRAPH_DEBUG
    }

    void set_edge_property(edge_t const& edge, id_t const& key,
                           id_t const& value) {

      // Add the property key to the "set" table to avoid default overwrite
      edge_map[edge].insert(key);
      // Set the user's property map
      self.graph_.set_edge_property(key, edge, value);
#ifdef BOOST_GRAPH_DEBUG
      // Tell the world
      std::cout << "(" << edge.first << "," << edge.second << "): "
                << key << " = " << value << std::endl;
#endif // BOOST_GRAPH_DEBUG
    }

    // Variables explicitly initialized
    dot_grammar const& self;
    // if subgraph_depth > 0, then we're processing a subgraph.
    int subgraph_depth; 

    // Keywords;
    const distinct_parser<> keyword_p;
    //
    // rules that make up the grammar
    //
    rule<ScannerT,id_closure::context_t> ID;
    rule<ScannerT,property_closure::context_t> a_list;
    rule<ScannerT,attr_list_closure::context_t> attr_list;
    rule_t port_location;
    rule_t port_angle;
    rule_t port;
    rule<ScannerT,node_id_closure::context_t> node_id;
    rule_t attr_stmt;
    rule<ScannerT,data_stmt_closure::context_t> data_stmt;
    rule<ScannerT,subgraph_closure::context_t> subgraph;
    rule_t edgeop;
    rule_t edgeRHS;
    rule_t stmt;
    rule_t stmt_list;
    rule_t the_grammar;

    
    // The grammar uses edge_head to dynamically set the syntax for edges
    // directed graphs: edge_head = '>', and so edgeop = "->"
    // undirected graphs: edge_head = '-', and so edgeop = "--"
    char edge_head;


    // 
    // Support data structures
    //

    nodes_t nodes;  // list of node names seen
    edges_t edges;  // list of edges seen
    node_map_t node_map; // remember the properties set for each node
    edge_map_t edge_map; // remember the properties set for each edge

    subgraph_nodes_t subgraph_nodes;   // per-subgraph lists of nodes
    subgraph_edges_t subgraph_edges;   // per-subgraph lists of edges
    
    props_t default_node_props;  // global default node properties
    props_t default_edge_props;  // global default edge properties
    subgraph_props_t subgraph_node_props;  // per-subgraph default node properties
    subgraph_props_t subgraph_edge_props;  // per-subgraph default edge properties
  }; // struct definition
}; // struct dot_grammar



//
// dot_skipper - GraphViz whitespace and comment skipper
//
struct dot_skipper : public grammar<dot_skipper>
{
    dot_skipper() {}

    template <typename ScannerT>
    struct definition
    {
        definition(dot_skipper const& /*self*/)  {
          // comment forms
          skip = space_p
               | comment_p("//")                 
               | comment_p("#")  
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
               | confix_p(str_p("/*") ,*anychar_p, str_p("*/"))
#else
               | confix_p("/*" ,*anychar_p, "*/")
#endif
               ;

#ifdef BOOST_SPIRIT_DEBUG
               BOOST_SPIRIT_DEBUG_RULE(skip);
#endif
        }

      rule<ScannerT>  skip;
      rule<ScannerT> const&
      start() const { return skip; }
    }; // definition
}; // dot_skipper

} // namespace graph
} // namespace detail

template <typename MultiPassIterator, typename MutableGraph>
bool read_graphviz(MultiPassIterator begin, MultiPassIterator end,
                   MutableGraph& graph, dynamic_properties& dp,
                   std::string const& node_id = "node_id") {
  using namespace boost;
  using namespace boost::spirit;

  typedef MultiPassIterator iterator_t;
  typedef skip_parser_iteration_policy< boost::detail::graph::dot_skipper>
    iter_policy_t;
  typedef scanner_policies<iter_policy_t> scanner_policies_t;
  typedef scanner<iterator_t, scanner_policies_t> scanner_t;

  detail::graph::mutate_graph_impl<MutableGraph> m_graph(graph, dp, node_id);

  boost::detail::graph::dot_grammar p(m_graph);
  boost::detail::graph::dot_skipper skip_p;

  iter_policy_t iter_policy(skip_p);
  scanner_policies_t policies(iter_policy);

  scanner_t scan(begin, end, policies);

  return p.parse(scan);
}

} // namespace boost

#endif // BOOST_READ_GRAPHVIZ_SPIRIT_HPP

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -