graph G {
  // preserve the ordering of the input
  ordering="out";

  // labels
  expr1[label="expr"];
  expr2[label="expr"];
  expr3[label="expr"];
  expr4[label="expr"];
  expr5[label="expr"];
  summand1[label="summand"];
  summand2[label="summand"];
  summand3[label="summand"];
  summand4[label="summand"];
  summand5[label="summand"];
  summand6[label="summand"];
  factor1[label="factor"];
  factor2[label="factor"];
  factor3[label="factor"];
  factor4[label="factor"];
  factor5[label="factor"];
  factor6[label="factor"];
  factor7[label="factor"];
  factor8[label="factor"];
  const1[label="const"];
  const2[label="const"];
  const3[label="const"];
  var1[label="var"];
  var2[label="var"];
  orop1[label="||"];
  orop2[label="||"];
  orop3[label="||"];
  andop1[label="&&"];
  notop1[label="!"];
  notop2[label="!"];
  lparen1[label="("];
  rparen1[label=")"];
  x[label="X"];
  z[label="Z"];
  false1[label="false"];
  true1[label="true"];
  true2[label="true"];

  // edges
  expr1 -- expr2;
  expr1 -- orop1;
  expr2 -- expr3;
  expr2 -- orop2;
  expr3 -- summand1;
  summand1 -- factor1;
  factor1 -- const1;
  const1 -- false1;
  expr2 -- summand2;
  summand2 -- summand3;
  summand2 -- andop1;
  summand3 -- factor2;
  factor2 -- const2;
  const2 -- true1;
  summand2 -- factor3;
  factor3 -- notop1;
  factor3 -- factor4;
  factor4 -- lparen1;
  factor4 -- expr4;
  factor4 -- rparen1;
  expr4 -- expr5;
  expr4 -- orop3;
  expr5 -- summand4;
  summand4 -- factor5;
  factor5 -- var1;
  var1 -- x;
  expr4 -- summand5;
  summand5 -- factor6;
  factor6 -- const3;
  const3 -- true2;
  expr1 -- summand6;
  summand6 -- factor7;
  factor7 -- notop2;
  factor7 -- factor8;
  factor8 -- var2;
  var2 -- z;
}
