Surprising expansion of complex edge statements

I have the following relatively complex edge statement:

graph {
    {a, b -- c} -- d

I’d expect this to be equivalent to:

graph {
	a -- d;
	b -- c;
	b -- d;
	c -- d;

That is: link all the node ids found on the left of the -- to all the node ids found on its right.

What actually happens is:

graph {
	a -- c;
	a -- d;
	b -- c;
	b -- d;
	c -- d;

There’s an unexpected (by me) edge statement in there: a -- c.

Is this expected behaviour? If so, could anyone link to how such complex edge statements are expanded, so that I can learn this rather than build (obviously incorrect) heuristics?

I think I might have worked it out. I’m using , to separate a and b -- c - that’s the issue, isn’t it?

If I use ;, it behaves as expected. What my edge statement actually means is nodes a and b linked to c, doesn’t it?

Yes. Don’t do that! Read the source code.

Is that serious advice?

I’m sorry, a little serious. Unfortunately, we are discussing an undocumented feature. If I’m not mistaken there’s no comma separated node list in Appendix D of the dot guide. But you can see where a comma separated node list is implemented in the cgraph parser as an alternative to subgraphs in edge statements. I’m sorry, I don’t remember any more why this was deemed a good idea when it was done. This construct is also in libagraph (predecessor of cgraph) but not the original libgraph circa 1988. The dot guide is clear that you can liberally use semicolons as statement separators, or trust the parser and only use whitespace most of the time.

Thank you for going out of your way to explain - twice, because this is something that was also pointed out to me by the graphviz twitter account.

It’s a bit of a relief, actually - it’s an undocumented feature, so it’s ok-ish for my own DOT parser / interpreter to not support it in exactly the same way as Graphviz does.

[sorry if this is too simplified for you, I don’t know your background]
Graphviz is a set of programs & interfaces, but I will assume you want to start with the dot program.
Dot is described here
Dot is “old school” - it is not interactive - no gui.

  1. Using any editor you like (maybe notepad to start), create a dot input file.
  2. start the windows cmd shell or powershell
  3. type dot -c ## just once to make sure dot will be ready to run
  4. to use dot, each time type:dot -Tpng yourfile.gv >yourfile.png ## this assumes you want a png output. It also assumes your input file suffix is .gv
  5. look at the output with a web prowser, Paint, or any photo display program

Ah, no, I’m relatively comfortable with DOT and its syntax, thanks :slight_smile: I was just getting confused by the distinction between commas and semi colons, the behaviour of the former not being documented (that I could find).

Just to give context to my initial (now solved) question, I was working on a stylesheet preprocessor for DOT. This caused me to reimplement a DOT parser, and tests led me to discover lots of weird corner cases I hadn’t realised were supported.

If you’re interested, here’s the outcome of this toy project: GitHub - nrinaudo/

Wow, that is my dumbest move of the month, and it is only the 12th! My answer was intended for another question entirely, but I was in a rush and plopped it here.
I feel like Emily Litella Emily Litella - Wikipedia
Sorry! Blush. “Never Mind”

If that’s your most embarrassing move of the month, congratulations, you’re doing great. I can think of half a dozen worse things I’ve done this week alone

We’re friendly; everything is fine. I wish I could recollect the train of thought that led to extending the graph language between libgraph and libAgraph. This is well before we realized other people might try to build on this work. I wonder if we should update the dotguide.

The dotguide definitely needs updating:

I am curious what happens when you build a Dot parser based on the docs because they are not accurate wrt parsing ([Documentation] The abstract grammar is missing a rule for edgeop (#133) · Issues · graphviz / graphviz · GitLab). I had never before seen the syntax Nicolas uses in this thread.

That last ticket is a little bit unfair. I built a parser using the linked guide, and I had absolutely no issue working out that edgeops were -- and -> - it’s explained just below. I’m assuming it’s not part of the grammar because it would be quite complicated to express “it’s – for graphs and → for directed graphs” as BNF.

I basically had two surprises:

  • that , syntax which is, as far as I can tell, not documented (and seems to be basically syntactic sugar for “a non-cluster graph with no attribute”)
  • the way edges are expended when their lhs and / or rhs are composed of multiple nodes.