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.
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;}
;
}
/* 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;
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 */