]> granicus.if.org Git - graphviz/commitdiff
Another try at fixing the bug involving the parser and edges involving subgraphs.
authorStephen North <north@pome.client.research.att.com>
Thu, 22 Aug 2013 18:33:12 +0000 (14:33 -0400)
committerStephen North <north@pome.client.research.att.com>
Thu, 22 Aug 2013 18:33:12 +0000 (14:33 -0400)
For example consider
digraph G { a -> b -> {c d} }
digraph G { {rank=same; X Y}  a -> X -> Y}
digraph G { a -> b -> {rank=same; X -> Y [color=red]} [color=blue]; }
In the last example the parser has to keep the anonymous subgraph around
as part of the edgelist being constructed, but when [color=blue] is parsed
it is no longer the "current subgraph".  There are Details. One idea is
that if this continues to be a source of errors, we could overhaul the
parser a bit more aggressively to make better use of the parser's own
stack and employ appropriate types for nodelist, subgraph, edgelist, attrlist
etc. rather than rely on the explicit stack gstack_t *S. Something to consider.

lib/cgraph/grammar.y

index d8cb343c6d0cd81752165078e27af95bdadad7c4..b7d95dfc3fd8256ae3a8e7138a1c487aac1268ff 100644 (file)
@@ -126,7 +126,7 @@ compound    :       simple rcompound optattr
 
 simple         :       nodelist | subgraph ;
 
-rcompound      :       T_edgeop {getedgeitems(1);} simple rcompound {getedgeitems(2); $$ = 1;}
+rcompound      :       T_edgeop {getedgeitems(1);} simple {getedgeitems(2);} rcompound {$$ = 1;}
                        |       /* empty */ {$$ = 0;}
                        ;
 
@@ -376,6 +376,10 @@ static void appendnode(char *name, char *port, char *sport)
 }
 
 /* apply current optional attrs to nodelist and clean up lists */
+/* what's bad is that this could also be endsubg.  also, you can't
+clean up S->subg in closesubg() because S->subg might be needed
+to construct edges.  these are the sort of notes you write to yourself
+in the future. */
 static void endnode()
 {
        item    *ptr;
@@ -385,6 +389,8 @@ static void endnode()
                applyattrs(ptr->u.n);
        deletelist(&(S->nodelist));
        deletelist(&(S->attrlist));
+       deletelist(&(S->edgelist));
+       S->subg = 0;  /* notice a pattern here? :-( */
 }
 
 /* edges - store up node/subg lists until optional edge key can be seen */