]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/boost/graph/detail/read_graphviz_spirit.hpp
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / boost / boost / graph / detail / read_graphviz_spirit.hpp
index d10bbc720cd6636dd17cbfad4a59c9eb63794f5e..b39ad7d631c2dbb935c236786f2a4982f792e633 100644 (file)
@@ -13,7 +13,7 @@
 //   Based on the grammar found at:
 //   https://web.archive.org/web/20041213234742/http://www.graphviz.org/cvs/doc/info/lang.html
 //
-//   See documentation for this code at: 
+//   See documentation for this code at:
 //     http://www.boost.org/libs/graph/doc/read_graphviz.html
 //
 
@@ -27,7 +27,6 @@
 #define PHOENIX_LIMIT 6
 #define BOOST_SPIRIT_CLOSURE_LIMIT 6
 
-
 #include <boost/spirit/include/classic_multi_pass.hpp>
 #include <boost/spirit/include/classic_core.hpp>
 #include <boost/spirit/include/classic_confix.hpp>
 #include <boost/graph/graphviz.hpp>
 #include <boost/throw_exception.hpp>
 
-namespace phoenix {
+namespace phoenix
+{
 // Workaround:  std::map::operator[] uses a different return type than all
 // other standard containers.  Phoenix doesn't account for that.
-template <typename TK, typename T0, typename T1>
-struct binary_operator<index_op, std::map<TK,T0>, T1>
+template < typename TK, typename T0, typename T1 >
+struct binary_operator< index_op, std::map< TK, T0 >, T1 >
 {
-    typedef typename std::map<TK,T0>::mapped_type& result_type;
-    static result_type eval(std::map<TK,T0>& container, T1 const& index)
-    { return container[index]; }
+    typedef typename std::map< TK, T0 >::mapped_type& result_type;
+    static result_type eval(std::map< TK, T0 >& container, T1 const& index)
+    {
+        return container[index];
+    }
 };
 } // namespace phoenix
 
-namespace boost {
-namespace detail {
-namespace graph {
-
-
-/////////////////////////////////////////////////////////////////////////////
-// Application-specific type definitions
-/////////////////////////////////////////////////////////////////////////////
-
-typedef std::set<edge_t> edges_t;
-typedef std::set<node_t> nodes_t;
-typedef std::set<id_t> ids_t;
-typedef std::map<edge_t,ids_t> edge_map_t;
-typedef std::map<node_t,ids_t> node_map_t;
-typedef std::map<id_t,id_t> props_t;
-typedef std::map<id_t,props_t> subgraph_props_t;
-typedef boost::function2<void, id_t const&, id_t const&> actor_t;
-typedef std::vector<edge_t> edge_stack_t;
-typedef std::map<id_t,nodes_t> subgraph_nodes_t;
-typedef std::map<id_t,edges_t> subgraph_edges_t;
-
-
-
-/////////////////////////////////////////////////////////////////////////////
-// Stack frames used by semantic actions
-/////////////////////////////////////////////////////////////////////////////
-struct id_closure : boost::spirit::classic::closure<id_closure, node_t> {
-  member1 name;
-};
-
-
-struct node_id_closure : boost::spirit::classic::closure<node_id_closure, node_t> {
-  member1 name;
-};
-
-struct attr_list_closure : boost::spirit::classic::closure<attr_list_closure, actor_t> {
-  member1 prop_actor;
-};
-
-struct property_closure : boost::spirit::classic::closure<property_closure, id_t, id_t> {
-  member1 key;
-  member2 value;
-};
-
-struct data_stmt_closure : boost::spirit::classic::closure<data_stmt_closure,
-                           nodes_t,nodes_t,edge_stack_t,bool,node_t> {
-  member1 sources;
-  member2 dests;
-  member3 edge_stack;
-  member4 saw_node;
-  member5 active_node;
-};
-
-struct subgraph_closure : boost::spirit::classic::closure<subgraph_closure,
-                          nodes_t, edges_t, node_t> {
-  member1 nodes;
-  member2 edges;
-  member3 name;
-};
+namespace boost
+{
+namespace detail
+{
+    namespace graph
+    {
 
-/////////////////////////////////////////////////////////////////////////////
-// Grammar and Actions for the DOT Language
-/////////////////////////////////////////////////////////////////////////////
-
-// Grammar for a dot file.
-struct dot_grammar : public boost::spirit::classic::grammar<dot_grammar> { 
-  mutate_graph& graph_;
-  explicit dot_grammar(mutate_graph& graph) : graph_(graph) { }
-
-  template <class ScannerT>
-  struct definition {
-   
-    definition(dot_grammar const& self) : self(self), subgraph_depth(0),
-    keyword_p("0-9a-zA-Z_") {
-      using namespace boost::spirit::classic;
-      using namespace phoenix;
-      
-      // RG - Future Work
-      // - Handle multi-line strings using \ line continuation
-      // - Make keywords case insensitive
-      ID 
-          = ( lexeme_d[((alpha_p | ch_p('_')) >> *(alnum_p | ch_p('_')))]
-            | real_p
-            | lexeme_d[confix_p('"', *c_escape_ch_p, '"')]
-            | comment_nest_p('<', '>')
-            )[ID.name = construct_<std::string>(arg1,arg2)]
-          ; 
-
-      a_list
-          = list_p( ID[(a_list.key = arg1),
-                       (a_list.value = "true")
-                      ]
-                    >> !( ch_p('=')
-                          >> ID[a_list.value = arg1])
-                          [phoenix::bind(&definition::call_prop_actor)
-                          (var(*this),a_list.key,a_list.value)],!ch_p(','));
-      
-      attr_list = +(ch_p('[') >> !a_list >> ch_p(']'));
-
-      // RG - disregard port id's for now.
-      port_location 
-          = (ch_p(':') >> ID)
-          | (ch_p(':') >> ch_p('(') >> ID >> ch_p(',') >> ID >> ch_p(')'))
-          ;
-
-      port_angle = ch_p('@') >> ID;
-
-      port
-          = port_location >> (!port_angle)
-          | port_angle >> (!port_location);
-
-
-      node_id
-          = ( ID[node_id.name = arg1] >> (!port) )
-             [phoenix::bind(&definition::memoize_node)(var(*this))];
-
-      graph_stmt
-          = (ID[graph_stmt.key = arg1] >>
-             ch_p('=') >>
-             ID[graph_stmt.value = arg1])
-        [phoenix::bind(&definition::call_graph_prop)
-         (var(*this),graph_stmt.key,graph_stmt.value)]
-        ; // Graph property.
-
-      attr_stmt
-          = (as_lower_d[keyword_p("graph")]
-             >> attr_list(actor_t(phoenix::bind(&definition::default_graph_prop)
-                                     (var(*this),arg1,arg2))))
-          | (as_lower_d[keyword_p("node")]
-             >> attr_list(actor_t(phoenix::bind(&definition::default_node_prop)
-                                     (var(*this),arg1,arg2))))
-          | (as_lower_d[keyword_p("edge")]
-             >> attr_list(actor_t(phoenix::bind(&definition::default_edge_prop)
-                                     (var(*this),arg1,arg2))))
-          ;
-
-      // edge_head is set depending on the graph type (directed/undirected)
-      edgeop = ch_p('-') >> ch_p(boost::ref(edge_head));
-
-      edgeRHS
-          =  +(    edgeop[(data_stmt.sources = data_stmt.dests),
-                          (data_stmt.dests = construct_<nodes_t>())]
-                   >> ( subgraph[data_stmt.dests = arg1]
-                      | node_id[phoenix::bind(&definition::insert_node)
-                                (var(*this),data_stmt.dests,arg1)]
-                      )
-                   [phoenix::bind(&definition::activate_edge)
-                    (var(*this),data_stmt.sources,data_stmt.dests,
-                     var(edges), var(default_edge_props))]
-              );
-      
-
-      // To avoid backtracking, edge, node, and subgraph statements are
-      // processed as one nonterminal.
-      data_stmt
-          = ( subgraph[(data_stmt.dests = arg1),// will get moved in rhs
-                       (data_stmt.saw_node = false)] 
-            | node_id[(phoenix::bind(&definition::insert_node)
-                       (var(*this),data_stmt.dests,arg1)),
-                      (data_stmt.saw_node = true),
+        /////////////////////////////////////////////////////////////////////////////
+        // Application-specific type definitions
+        /////////////////////////////////////////////////////////////////////////////
+
+        typedef std::set< edge_t > edges_t;
+        typedef std::set< node_t > nodes_t;
+        typedef std::set< id_t > ids_t;
+        typedef std::map< edge_t, ids_t > edge_map_t;
+        typedef std::map< node_t, ids_t > node_map_t;
+        typedef std::map< id_t, id_t > props_t;
+        typedef std::map< id_t, props_t > subgraph_props_t;
+        typedef boost::function2< void, id_t const&, id_t const& > actor_t;
+        typedef std::vector< edge_t > edge_stack_t;
+        typedef std::map< id_t, nodes_t > subgraph_nodes_t;
+        typedef std::map< id_t, edges_t > subgraph_edges_t;
+
+        /////////////////////////////////////////////////////////////////////////////
+        // Stack frames used by semantic actions
+        /////////////////////////////////////////////////////////////////////////////
+        struct id_closure
+        : boost::spirit::classic::closure< id_closure, node_t >
+        {
+            member1 name;
+        };
+
+        struct node_id_closure
+        : boost::spirit::classic::closure< node_id_closure, node_t >
+        {
+            member1 name;
+        };
+
+        struct attr_list_closure
+        : boost::spirit::classic::closure< attr_list_closure, actor_t >
+        {
+            member1 prop_actor;
+        };
+
+        struct property_closure
+        : boost::spirit::classic::closure< property_closure, id_t, id_t >
+        {
+            member1 key;
+            member2 value;
+        };
+
+        struct data_stmt_closure
+        : boost::spirit::classic::closure< data_stmt_closure, nodes_t, nodes_t,
+              edge_stack_t, bool, node_t >
+        {
+            member1 sources;
+            member2 dests;
+            member3 edge_stack;
+            member4 saw_node;
+            member5 active_node;
+        };
+
+        struct subgraph_closure
+        : boost::spirit::classic::closure< subgraph_closure, nodes_t, edges_t,
+              node_t >
+        {
+            member1 nodes;
+            member2 edges;
+            member3 name;
+        };
+
+        /////////////////////////////////////////////////////////////////////////////
+        // Grammar and Actions for the DOT Language
+        /////////////////////////////////////////////////////////////////////////////
+
+        // Grammar for a dot file.
+        struct dot_grammar
+        : public boost::spirit::classic::grammar< dot_grammar >
+        {
+            mutate_graph& graph_;
+            explicit dot_grammar(mutate_graph& graph) : graph_(graph) {}
+
+            template < class ScannerT > struct definition
+            {
+
+                definition(dot_grammar const& self)
+                : self(self), subgraph_depth(0), keyword_p("0-9a-zA-Z_")
+                {
+                    using namespace boost::spirit::classic;
+                    using namespace phoenix;
+
+                    // RG - Future Work
+                    // - Handle multi-line strings using \ line continuation
+                    // - Make keywords case insensitive
+                    ID = (lexeme_d[(
+                              (alpha_p | ch_p('_')) >> *(alnum_p | ch_p('_')))]
+                        | real_p | lexeme_d[confix_p('"', *c_escape_ch_p, '"')]
+                        | comment_nest_p('<', '>'))[ID.name
+                        = construct_< std::string >(arg1, arg2)];
+
+                    a_list = list_p(
+                        ID[(a_list.key = arg1), (a_list.value = "true")] >> !(
+                            ch_p('=') >> ID[a_list.value = arg1])[phoenix::bind(
+                            &definition::call_prop_actor)(
+                            var(*this), a_list.key, a_list.value)],
+                        !ch_p(','));
+
+                    attr_list = +(ch_p('[') >> !a_list >> ch_p(']'));
+
+                    // RG - disregard port id's for now.
+                    port_location = (ch_p(':') >> ID)
+                        | (ch_p(':') >> ch_p('(') >> ID >> ch_p(',') >> ID
+                            >> ch_p(')'));
+
+                    port_angle = ch_p('@') >> ID;
+
+                    port = port_location >> (!port_angle)
+                        | port_angle >> (!port_location);
+
+                    node_id
+                        = (ID[node_id.name = arg1] >> (!port))[phoenix::bind(
+                            &definition::memoize_node)(var(*this))];
+
+                    graph_stmt = (ID[graph_stmt.key = arg1] >> ch_p('=')
+                        >> ID[graph_stmt.value = arg1])[phoenix::bind(
+                        &definition::call_graph_prop)(var(*this),
+                        graph_stmt.key, graph_stmt.value)]; // Graph property.
+
+                    attr_stmt
+                        = (as_lower_d[keyword_p("graph")] >> attr_list(actor_t(
+                               phoenix::bind(&definition::default_graph_prop)(
+                                   var(*this), arg1, arg2))))
+                        | (as_lower_d[keyword_p("node")] >> attr_list(actor_t(
+                               phoenix::bind(&definition::default_node_prop)(
+                                   var(*this), arg1, arg2))))
+                        | (as_lower_d[keyword_p("edge")] >> attr_list(actor_t(
+                               phoenix::bind(&definition::default_edge_prop)(
+                                   var(*this), arg1, arg2))));
+
+                    // edge_head is set depending on the graph type
+                    // (directed/undirected)
+                    edgeop = ch_p('-') >> ch_p(boost::ref(edge_head));
+
+                    edgeRHS = +(edgeop[(data_stmt.sources = data_stmt.dests),
+                                    (data_stmt.dests = construct_< nodes_t >())]
+                        >> (subgraph[data_stmt.dests = arg1]
+                            | node_id[phoenix::bind(&definition::insert_node)(
+                                var(*this), data_stmt.dests, arg1)])
+                            [phoenix::bind(&definition::activate_edge)(
+                                var(*this), data_stmt.sources, data_stmt.dests,
+                                var(edges), var(default_edge_props))]);
+
+                    // To avoid backtracking, edge, node, and subgraph
+                    // statements are processed as one nonterminal.
+                    data_stmt
+                        = (subgraph[(data_stmt.dests
+                                        = arg1), // will get moved in rhs
+                               (data_stmt.saw_node = false)]
+                              | node_id[(phoenix::bind(
+                                            &definition::insert_node)(
+                                            var(*this), data_stmt.dests, arg1)),
+                                  (data_stmt.saw_node = true),
 #ifdef BOOST_GRAPH_DEBUG
-                      (std::cout << val("AcTive Node: ") << arg1 << "\n"),
+                                  (std::cout << val("AcTive Node: ") << arg1
+                                             << "\n"),
 #endif // BOOST_GRAPH_DEBUG
-                      (data_stmt.active_node = arg1)]
-            ) >> if_p(edgeRHS)[
-                     !attr_list(
-                       actor_t(phoenix::bind(&definition::edge_prop)
-                               (var(*this),arg1,arg2)))
-                  ].else_p[
-                     if_p(data_stmt.saw_node)[
-                         !attr_list(
-                           actor_t(phoenix::bind(&definition::node_prop)
-                                   (var(*this),arg1,arg2)))
-                     ] // otherwise it's a subgraph, nothing more to do.
-                  ];
-
-
-      stmt
-          = graph_stmt 
-          | attr_stmt
-          | data_stmt
-          ;
-
-      stmt_list = *( stmt >> !ch_p(';') );
-
-      subgraph
-          = !(  as_lower_d[keyword_p("subgraph")]
-                >> (!ID[(subgraph.name = arg1), 
-                        (subgraph.nodes = (var(subgraph_nodes))[arg1]),
-                        (subgraph.edges = (var(subgraph_edges))[arg1])])
-                )
-          >> ch_p('{')[++var(subgraph_depth)]
-          >> stmt_list 
-          >> ch_p('}')[--var(subgraph_depth)]
-                      [(var(subgraph_nodes))[subgraph.name] = subgraph.nodes]
-                      [(var(subgraph_edges))[subgraph.name] = subgraph.edges]
-                     
-          | as_lower_d[keyword_p("subgraph")]
-                >> ID[(subgraph.nodes = (var(subgraph_nodes))[arg1]),
-                      (subgraph.edges = (var(subgraph_edges))[arg1])]
-          ;
-
-      the_grammar
-          = (!as_lower_d[keyword_p("strict")])
-            >>  ( as_lower_d[keyword_p("graph")][
-                   (var(edge_head) = '-'),
-                   (phoenix::bind(&definition::check_undirected)(var(*this)))]
-                | as_lower_d[keyword_p("digraph")][
-                   (var(edge_head) = '>'),
-                   (phoenix::bind(&definition::check_directed)(var(*this)))]
-                )
-            >> (!ID) >> ch_p('{') >> stmt_list >> ch_p('}');
-
-    } // definition()
-
-    typedef boost::spirit::classic::rule<ScannerT> rule_t;
-
-    rule_t const& start() const { return the_grammar; }
-
-
-    //  
-    // Semantic actions
-    //
-
-    void check_undirected() {
-      if(self.graph_.is_directed())
-          boost::throw_exception(boost::undirected_graph_error());
-    }
-
-    void check_directed() {
-      if(!self.graph_.is_directed())
-          boost::throw_exception(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()));
+                                  (data_stmt.active_node = arg1)])
+                        >> if_p(edgeRHS)[!attr_list(actor_t(phoenix::bind(
+                                             &definition::edge_prop)(
+                                             var(*this), arg1, arg2)))]
+                               .else_p[if_p(data_stmt.saw_node)[!attr_list(
+                                   actor_t(phoenix::bind(
+                                       &definition::node_prop)(var(*this), arg1,
+                                       arg2)))] // otherwise it's a subgraph,
+                                                // nothing more to do.
+                    ];
+
+                    stmt = graph_stmt | attr_stmt | data_stmt;
+
+                    stmt_list = *(stmt >> !ch_p(';'));
+
+                    subgraph = !(as_lower_d[keyword_p("subgraph")]
+                                   >> (!ID[(subgraph.name = arg1),
+                                       (subgraph.nodes
+                                           = (var(subgraph_nodes))[arg1]),
+                                       (subgraph.edges
+                                           = (var(subgraph_edges))[arg1])]))
+                            >> ch_p('{')[++var(subgraph_depth)] >> stmt_list
+                            >> ch_p('}')[--var(subgraph_depth)]
+                                        [(var(subgraph_nodes))[subgraph.name]
+                                            = subgraph.nodes]
+                                        [(var(subgraph_edges))[subgraph.name]
+                                            = subgraph.edges]
+
+                        | as_lower_d[keyword_p("subgraph")]
+                            >> ID[(subgraph.nodes
+                                      = (var(subgraph_nodes))[arg1]),
+                                (subgraph.edges = (var(subgraph_edges))[arg1])];
+
+                    the_grammar = (!as_lower_d[keyword_p("strict")])
+                        >> (as_lower_d[keyword_p(
+                                "graph")][(var(edge_head) = '-'),
+                                (phoenix::bind(&definition::check_undirected)(
+                                    var(*this)))]
+                            | as_lower_d[keyword_p(
+                                "digraph")][(var(edge_head) = '>'),
+                                (phoenix::bind(&definition::check_directed)(
+                                    var(*this)))])
+                        >> (!ID) >> ch_p('{') >> stmt_list >> ch_p('}');
+
+                } // definition()
+
+                typedef boost::spirit::classic::rule< ScannerT > rule_t;
+
+                rule_t const& start() const { return the_grammar; }
+
+                //
+                // Semantic actions
+                //
+
+                void check_undirected()
+                {
+                    if (self.graph_.is_directed())
+                        boost::throw_exception(boost::undirected_graph_error());
+                }
+
+                void check_directed()
+                {
+                    if (!self.graph_.is_directed())
+                        boost::throw_exception(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;
+                        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 {
+       // 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;
+                        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.
+                    }
+                }
+
+                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;
+                            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) {
+                            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;
+                    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);
+                    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;
+                    // 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) {
+                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);
+                    // 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, 
+                    // Tell the world
+#if 0 // RG - edge representation changed,
             std::cout << "(" << edge.first << "," << edge.second << "): "
 #else
-            std::cout << "an edge: " 
+                    std::cout << "an edge: "
 #endif // 0
-                << key << " = " << value << std::endl;
+                    << 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::classic::distinct_parser<> keyword_p;
-    //
-    // rules that make up the grammar
-    //
-    boost::spirit::classic::rule<ScannerT,id_closure::context_t> ID;
-    boost::spirit::classic::rule<ScannerT,property_closure::context_t> a_list;
-    boost::spirit::classic::rule<ScannerT,attr_list_closure::context_t> attr_list;
-    rule_t port_location;
-    rule_t port_angle;
-    rule_t port;
-    boost::spirit::classic::rule<ScannerT,node_id_closure::context_t> node_id;
-    boost::spirit::classic::rule<ScannerT,property_closure::context_t> graph_stmt;
-    rule_t attr_stmt;
-    boost::spirit::classic::rule<ScannerT,data_stmt_closure::context_t> data_stmt;
-    boost::spirit::classic::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::classic::grammar<dot_skipper>
-{
-    dot_skipper() {}
-
-    template <typename ScannerT>
-    struct definition
-    {
-        definition(dot_skipper const& /*self*/)  {
-          using namespace boost::spirit::classic;
-          using namespace phoenix;
-          // comment forms
-          skip = eol_p >> comment_p("#")  
-               | space_p
-               | comment_p("//")                 
+                }
+
+                // Variables explicitly initialized
+                dot_grammar const& self;
+                // if subgraph_depth > 0, then we're processing a subgraph.
+                int subgraph_depth;
+
+                // Keywords;
+                const boost::spirit::classic::distinct_parser<> keyword_p;
+                //
+                // rules that make up the grammar
+                //
+                boost::spirit::classic::rule< ScannerT, id_closure::context_t >
+                    ID;
+                boost::spirit::classic::rule< ScannerT,
+                    property_closure::context_t >
+                    a_list;
+                boost::spirit::classic::rule< ScannerT,
+                    attr_list_closure::context_t >
+                    attr_list;
+                rule_t port_location;
+                rule_t port_angle;
+                rule_t port;
+                boost::spirit::classic::rule< ScannerT,
+                    node_id_closure::context_t >
+                    node_id;
+                boost::spirit::classic::rule< ScannerT,
+                    property_closure::context_t >
+                    graph_stmt;
+                rule_t attr_stmt;
+                boost::spirit::classic::rule< ScannerT,
+                    data_stmt_closure::context_t >
+                    data_stmt;
+                boost::spirit::classic::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::classic::grammar< dot_skipper >
+        {
+            dot_skipper() {}
+
+            template < typename ScannerT > struct definition
+            {
+                definition(dot_skipper const& /*self*/)
+                {
+                    using namespace boost::spirit::classic;
+                    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("*/"))
+                        | confix_p(str_p("/*"), *anychar_p, str_p("*/"))
 #else
-               | confix_p("/*" ,*anychar_p, "*/")
+                        | confix_p("/*", *anychar_p, "*/")
 #endif
-               ;
+                        ;
 
 #ifdef BOOST_SPIRIT_DEBUG
-               BOOST_SPIRIT_DEBUG_RULE(skip);
+                    BOOST_SPIRIT_DEBUG_RULE(skip);
 #endif
-        }
+                }
 
-      boost::spirit::classic::rule<ScannerT>  skip;
-      boost::spirit::classic::rule<ScannerT> const&
-      start() const { return skip; }
-    }; // definition
-}; // dot_skipper
+                boost::spirit::classic::rule< ScannerT > skip;
+                boost::spirit::classic::rule< ScannerT > const& start() const
+                {
+                    return skip;
+                }
+            }; // definition
+        }; // dot_skipper
 
-} // namespace graph
+    } // namespace graph
 } // namespace detail
 
-template <typename MultiPassIterator, typename MutableGraph>
+template < typename MultiPassIterator, typename MutableGraph >
 bool read_graphviz_spirit(MultiPassIterator begin, MultiPassIterator end,
-                          MutableGraph& graph, dynamic_properties& dp,
-                          std::string const& node_id = "node_id") {
-  using namespace boost;
-  using namespace boost::spirit::classic;
+    MutableGraph& graph, dynamic_properties& dp,
+    std::string const& node_id = "node_id")
+{
+    using namespace boost;
+    using namespace boost::spirit::classic;
 
-  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;
+    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::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;
+    ::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);
+    iter_policy_t iter_policy(skip_p);
+    scanner_policies_t policies(iter_policy);
 
-  scanner_t scan(begin, end, policies);
+    scanner_t scan(begin, end, policies);
 
-  bool ok = p.parse(scan);
-  m_graph.finish_building_graph();
-  return ok;
+    bool ok = p.parse(scan);
+    m_graph.finish_building_graph();
+    return ok;
 }
 
 } // namespace boost