📄 read_graphviz_spirit.hpp
字号:
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 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 - Store as a graph property. void default_graph_prop(id_t const& key, id_t const& value) {#ifdef BOOST_GRAPH_DEBUG std::cout << key << " = " << value << std::endl;#endif // BOOST_GRAPH_DEBUG self.graph_.set_graph_property(key, value); } // 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 call_graph_prop(std::string const& lhs, std::string const& rhs) { // If first and last characters of the rhs are double-quotes, // remove them. if (!rhs.empty() && rhs[0] == '"' && rhs[rhs.size() - 1] == '"') this->default_graph_prop(lhs, rhs.substr(1, rhs.size()-2)); else this->default_graph_prop(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#if 0 // RG - edge representation changed, std::cout << "(" << edge.first << "," << edge.second << "): "#else std::cout << "an edge: " #endif // 0 << 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 boost::spirit::distinct_parser<> keyword_p; // // rules that make up the grammar // boost::spirit::rule<ScannerT,id_closure::context_t> ID; boost::spirit::rule<ScannerT,property_closure::context_t> a_list; boost::spirit::rule<ScannerT,attr_list_closure::context_t> attr_list; rule_t port_location; rule_t port_angle; rule_t port; boost::spirit::rule<ScannerT,node_id_closure::context_t> node_id; boost::spirit::rule<ScannerT,property_closure::context_t> graph_stmt; rule_t attr_stmt; boost::spirit::rule<ScannerT,data_stmt_closure::context_t> data_stmt; boost::spirit::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 boost::spirit::grammar<dot_skipper>{ dot_skipper() {} template <typename ScannerT> struct definition { definition(dot_skipper const& /*self*/) { using namespace boost::spirit; using namespace phoenix; // comment forms skip = eol_p >> comment_p("#") | space_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 } boost::spirit::rule<ScannerT> skip; boost::spirit::rule<ScannerT> const& start() const { return skip; } }; // definition}; // dot_skipper} // namespace graph} // namespace detailtemplate <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; ::boost::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 + -