Graphviz 13.0.0~dev.20241220.2304
Loading...
Searching...
No Matches
gmlparse.y
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11%require "3.0"
12
13 /* By default, Bison emits a parser using symbols prefixed with "yy". Graphviz
14 * contains multiple Bison-generated parsers, so we alter this prefix to avoid
15 * symbol clashes.
16 */
17%define api.prefix {gml}
18
19%{
20#include <stdlib.h>
21#include <string.h>
22#include <arith.h>
23#include <gml2gv.h>
24#include <assert.h>
25#include <cgraph/list.h>
26#include <util/agxbuf.h>
27#include <util/alloc.h>
28#include <util/exit.h>
29
30static gmlgraph* G;
31static gmlnode* N;
32static gmledge* E;
33
34static attrs_t *L;
35
36static void free_attrs(attrs_t *a) {
37 attrs_free(a);
38 free(a);
39}
40
41DEFINE_LIST_WITH_DTOR(dts, attrs_t *, free_attrs)
42static dts_t liststk;
43
44static char *sortToStr(unsigned short sort);
45
46void free_node(gmlnode *p) {
47 if (!p) return;
48 attrs_free(&p->attrlist);
49 free (p);
50}
51
52void free_edge(gmledge *p) {
53 if (!p) return;
54 attrs_free(&p->attrlist);
55 free (p);
56}
57
58void free_graph(gmlgraph *p) {
59 if (!p) return;
60 nodes_free(&p->nodelist);
61 edges_free(&p->edgelist);
62 attrs_free(&p->attrlist);
63 graphs_free(p->graphlist);
64 free(p->graphlist);
65 free (p);
66}
67
68static void
69cleanup (void)
70{
71 dts_free(&liststk);
72 if (L) {
74 L = NULL;
75 }
76 if (N) {
77 free_node(N);
78 N = NULL;
79 }
80 if (E) {
81 free_edge(E);
82 E = NULL;
83 }
84 if (G) {
86 G = NULL;
87 }
88}
89
90static void
91pushAlist (void)
92{
93 attrs_t *const lp = gv_alloc(sizeof(attrs_t));
94
95 if (L) {
96 dts_push_back(&liststk, L);
97 }
98 L = lp;
99}
100
101static attrs_t *popAlist(void) {
102 attrs_t *lp = L;
103
104 if (!dts_is_empty(&liststk))
105 L = dts_pop_back(&liststk);
106 else
107 L = NULL;
108
109 return lp;
110}
111
112static void
113popG (void)
114{
115 G = G->parent;
116}
117
118static void
119pushG (void)
120{
121 gmlgraph* g = gv_alloc(sizeof(gmlgraph));
122
123 g->graphlist = gv_alloc(sizeof(graphs_t));
124 g->parent = G;
125 g->directed = -1;
126
127 if (G)
128 graphs_append(G->graphlist, g);
129
130 G = g;
131}
132
133static gmlnode*
134mkNode (void)
135{
136 gmlnode* np = gv_alloc(sizeof(gmlnode));
137 np->id = NULL;
138 return np;
139}
140
141static gmledge*
142mkEdge (void)
143{
144 gmledge* ep = gv_alloc(sizeof(gmledge));
145 ep->source = NULL;
146 ep->target = NULL;
147 return ep;
148}
149
150static gmlattr *mkAttr(char* name, unsigned short sort, unsigned short kind,
151 char* str, attrs_t* list) {
152 gmlattr* gp = gv_alloc(sizeof(gmlattr));
153
154 assert (name || sort);
155 if (!name)
156 name = gv_strdup (sortToStr (sort));
157 gp->sort = sort;
158 gp->kind = kind;
159 gp->name = name;
160 if (str)
161 gp->u.value = str;
162 else {
163 if (list != NULL && attrs_is_empty(list)) {
164 free_attrs(list);
165 list = 0;
166 }
167 gp->u.lp = list;
168 }
169 return gp;
170}
171
172static int
173setDir (char* d)
174{
175 gmlgraph* g;
176 int dir = atoi (d);
177
178 free (d);
179 if (dir < 0) dir = -1;
180 else if (dir > 0) dir = 1;
181 else dir = 0;
182 G->directed = dir;
183
184 if (dir >= 0) {
185 for (g = G->parent; g; g = g->parent) {
186 if (g->directed < 0)
187 g->directed = dir;
188 else if (g->directed != dir)
189 return 1;
190 }
191 }
192
193 return 0;
194}
195
196%}
197%union {
198 int i;
199 char *str;
200 gmlnode* np;
201 gmledge* ep;
202 gmlattr* ap;
203 attrs_t *list;
204}
205
209%token STYLE LINE POINT
211%token <str> INTEGER REAL STRING ID NAME
212%token <list> LIST
213
214%type <np> node
215%type <ep> edge
216%type <list> attrlist
217%type <ap> alistitem
218
219%%
220graph : optalist hdr body {gmllexeof(); if (G->parent) popG(); }
221 | error { cleanup(); YYABORT; }
222 |
223 ;
224
225hdr : GRAPH { pushG(); }
226 ;
227
228body : '[' optglist ']'
229 ;
230
231optglist : glist
232 | /* empty */
233 ;
234
235glist : glist glistitem
236 | glistitem
237 ;
238
239glistitem : node { nodes_append(&G->nodelist, $1); }
240 | edge { edges_append(&G->edgelist, $1); }
241 | hdr body
243 if (setDir($2)) {
244 yyerror("mixed directed and undirected graphs");
245 cleanup ();
246 YYABORT;
247 }
248 }
249 | ID INTEGER { attrs_append(&G->attrlist, mkAttr(gv_strdup("id"), 0, INTEGER, $2, 0)); }
250 | alistitem { attrs_append(&G->attrlist, $1); }
251 ;
252
253node : NODE { N = mkNode(); } '[' nlist ']' { $$ = N; N = NULL; }
254 ;
255
256nlist : nlist nlistitem
257 | nlistitem
258 ;
259
260nlistitem : ID INTEGER { N->id = $2; }
261 | alistitem { attrs_append(&N->attrlist, $1); }
262 ;
263
264edge : EDGE { E = mkEdge(); } '[' elist ']' { $$ = E; E = NULL; }
265 ;
266
267elist : elist elistitem
268 | elistitem
269 ;
270
271elistitem : SOURCE INTEGER { E->source = $2; }
272 | TARGET INTEGER { E->target = $2; }
273 | ID INTEGER { attrs_append(&E->attrlist, mkAttr(gv_strdup("id"), 0, INTEGER, $2, 0)); }
274 | alistitem { attrs_append(&E->attrlist, $1); }
275 ;
276
277attrlist : '[' {pushAlist(); } optalist ']' { $$ = popAlist(); }
278 ;
279
280optalist : alist
281 | /* empty */
282 ;
283
284alist : alist alistitem { attrs_append(L, $2); }
285 | alistitem { attrs_append(L, $1); }
286 ;
287
289 | NAME REAL { $$ = mkAttr ($1, 0, REAL, $2, 0); }
290 | NAME STRING { $$ = mkAttr ($1, 0, STRING, $2, 0); }
291 | NAME attrlist { $$ = mkAttr ($1, 0, LIST, 0, $2); }
292 | XVAL REAL { $$ = mkAttr (0, XVAL, REAL, $2, 0); }
293 | XVAL INTEGER { $$ = mkAttr (0, XVAL, REAL, $2, 0); }
294 | YVAL REAL { $$ = mkAttr (0, YVAL, REAL, $2, 0); }
295 | WVAL REAL { $$ = mkAttr (0, WVAL, REAL, $2, 0); }
296 | HVAL REAL { $$ = mkAttr (0, HVAL, REAL, $2, 0); }
297 | LABEL STRING { $$ = mkAttr (0, LABEL, STRING, $2, 0); }
298 | GRAPHICS attrlist { $$ = mkAttr (0, GRAPHICS, LIST, 0, $2); }
300 | TYPE STRING { $$ = mkAttr (0, TYPE, STRING, $2, 0); }
301 | FILL STRING { $$ = mkAttr (0, FILL, STRING, $2, 0); }
302 | OUTLINE STRING { $$ = mkAttr (0, OUTLINE, STRING, $2, 0); }
305 | WIDTH REAL { $$ = mkAttr (0, WIDTH, REAL, $2, 0); }
306 | WIDTH INTEGER { $$ = mkAttr (0, WIDTH, INTEGER, $2, 0); }
307 | STYLE STRING { $$ = mkAttr (0, STYLE, STRING, $2, 0); }
308 | STYLE attrlist { $$ = mkAttr (0, STYLE, LIST, 0, $2); }
309 | LINE attrlist { $$ = mkAttr (0, LINE, LIST, 0, $2); }
310 | POINT attrlist { $$ = mkAttr (0, POINT, LIST, 0, $2); }
311 | TEXT STRING { $$ = mkAttr (0, TEXT, STRING, $2, 0); }
312 | FONTNAME STRING { $$ = mkAttr (0, FONTNAME, STRING, $2, 0); }
313 | FONTSIZE INTEGER { $$ = mkAttr (0, FONTNAME, INTEGER, $2, 0); }
314 | COLOR STRING { $$ = mkAttr (0, COLOR, STRING, $2, 0); }
315 ;
316
317%%
318
320 if (!p) return;
321 if (p->kind == LIST && p->u.lp)
322 free_attrs(p->u.lp);
323 else
324 free (p->u.value);
325 free (p->name);
326 free (p);
327}
328
329static void deparseList(attrs_t *alist, agxbuf *xb);
330
331static void
333{
334 if (ap->kind == LIST) {
335 agxbprint (xb, "%s ", ap->name);
336 deparseList (ap->u.lp, xb);
337 }
338 else if (ap->kind == STRING) {
339 agxbprint (xb, "%s \"%s\"", ap->name, ap->u.value);
340 }
341 else {
342 agxbprint (xb, "%s %s", ap->name, ap->u.value);
343 }
344}
345
346static void deparseList(attrs_t *alist, agxbuf *xb) {
347 agxbput (xb, "[ ");
348 for (size_t i = 0; alist != NULL && i < attrs_size(alist); ++i) {
349 gmlattr *const ap = attrs_get(alist, i);
350 deparseAttr (ap, xb);
351 agxbputc (xb, ' ');
352 }
353 agxbput (xb, "]");
354
355}
356
357static void
359{
360 char* str;
361
362 if (ap->kind == LIST) {
363 deparseList (ap->u.lp, xb);
364 str = agxbuse (xb);
365 }
366 else
367 str = ap->u.value;
368
369 agsafeset (obj, ap->name, str, "");
370}
371
372static void addNodeLabelGraphics(Agnode_t *np, attrs_t *alist, agxbuf *unk) {
373 int cnt = 0;
374
375 if (!alist)
376 return;
377
378 for (size_t i = 0; i < attrs_size(alist); ++i) {
379 gmlattr *const ap = attrs_get(alist, i);
380 if (ap->sort == TEXT) {
381 agsafeset (np, "label", ap->u.value, "");
382 }
383 else if (ap->sort == COLOR) {
384 agsafeset (np, "fontcolor", ap->u.value, "");
385 }
386 else if (ap->sort == FONTSIZE) {
387 agsafeset (np, "fontsize", ap->u.value, "");
388 }
389 else if (ap->sort == FONTNAME) {
390 agsafeset (np, "fontname", ap->u.value, "");
391 }
392 else {
393 if (cnt)
394 agxbputc (unk, ' ');
395 else {
396 agxbput (unk, "[ ");
397 }
398 deparseAttr (ap, unk);
399 cnt++;
400 }
401 }
402
403 if (cnt) {
404 agxbput (unk, " ]");
405 agsafeset (np, "LabelGraphics", agxbuse (unk), "");
406 }
407 else
408 agxbclear (unk);
409}
410
411static void addEdgeLabelGraphics(Agedge_t *ep, attrs_t *alist, agxbuf *xb,
412 agxbuf *unk) {
413 char* x = "0";
414 char* y = "0";
415 int cnt = 0;
416
417 if (!alist)
418 return;
419
420 for (size_t i = 0; i < attrs_size(alist); ++i) {
421 gmlattr *const ap = attrs_get(alist, i);
422 if (ap->sort == TEXT) {
423 agsafeset (ep, "label", ap->u.value, "");
424 }
425 else if (ap->sort == COLOR) {
426 agsafeset (ep, "fontcolor", ap->u.value, "");
427 }
428 else if (ap->sort == FONTSIZE) {
429 agsafeset (ep, "fontsize", ap->u.value, "");
430 }
431 else if (ap->sort == FONTNAME) {
432 agsafeset (ep, "fontname", ap->u.value, "");
433 }
434 else if (ap->sort == XVAL) {
435 x = ap->u.value;
436 }
437 else if (ap->sort == YVAL) {
438 y = ap->u.value;
439 }
440 else {
441 if (cnt)
442 agxbputc (unk, ' ');
443 else {
444 agxbput (unk, "[ ");
445 }
446 deparseAttr (ap, unk);
447 cnt++;
448 }
449 }
450
451 agxbprint (xb, "%s,%s", x, y);
452 agsafeset (ep, "lp", agxbuse (xb), "");
453
454 if (cnt) {
455 agxbput (unk, " ]");
456 agsafeset (ep, "LabelGraphics", agxbuse (unk), "");
457 }
458 else
459 agxbclear (unk);
460}
461
462static void addNodeGraphics(Agnode_t *np, attrs_t *alist, agxbuf *xb,
463 agxbuf *unk) {
464 char* x = "0";
465 char* y = "0";
466 char buf[BUFSIZ];
467 double d;
468 int cnt = 0;
469
470 for (size_t i = 0; alist != NULL && i < attrs_size(alist); ++i) {
471 gmlattr *const ap = attrs_get(alist, i);
472 if (ap->sort == XVAL) {
473 x = ap->u.value;
474 }
475 else if (ap->sort == YVAL) {
476 y = ap->u.value;
477 }
478 else if (ap->sort == WVAL) {
479 d = atof (ap->u.value);
480 snprintf(buf, sizeof(buf), "%.04f", d/72.0);
481 agsafeset (np, "width", buf, "");
482 }
483 else if (ap->sort == HVAL) {
484 d = atof (ap->u.value);
485 snprintf(buf, sizeof(buf), "%.04f", d/72.0);
486 agsafeset (np, "height", buf, "");
487 }
488 else if (ap->sort == TYPE) {
489 agsafeset (np, "shape", ap->u.value, "");
490 }
491 else if (ap->sort == FILL) {
492 agsafeset (np, "color", ap->u.value, "");
493 }
494 else if (ap->sort == OUTLINE) {
495 agsafeset (np, "pencolor", ap->u.value, "");
496 }
497 else if (ap->sort == WIDTH || ap->sort == OUTLINEWIDTH) {
498 agsafeset (np, "penwidth", ap->u.value, "");
499 }
500 else if (ap->sort == STYLE || ap->sort == OUTLINESTYLE) {
501 agsafeset (np, "style", ap->u.value, "");
502 }
503 else {
504 if (cnt)
505 agxbputc (unk, ' ');
506 else {
507 agxbput (unk, "[ ");
508 }
509 deparseAttr (ap, unk);
510 cnt++;
511 }
512 }
513
514 agxbprint (xb, "%s,%s", x, y);
515 agsafeset (np, "pos", agxbuse (xb), "");
516
517 if (cnt) {
518 agxbput (unk, " ]");
519 agsafeset (np, "graphics", agxbuse (unk), "");
520 }
521 else
522 agxbclear (unk);
523}
524
525static void addEdgePoint(Agedge_t *ep, attrs_t *alist, agxbuf *xb) {
526 char* x = "0";
527 char* y = "0";
528
529 for (size_t i = 0; alist != NULL && i < attrs_size(alist); ++i) {
530 gmlattr *const ap = attrs_get(alist, i);
531 if (ap->sort == XVAL) {
532 x = ap->u.value;
533 }
534 else if (ap->sort == YVAL) {
535 y = ap->u.value;
536 }
537 else {
538 fprintf (stderr, "non-X/Y field in point attribute");
539 unknown ((Agobj_t*)ep, ap, xb);
540 }
541 }
542
543 if (agxblen(xb)) agxbputc (xb, ' ');
544 agxbprint (xb, "%s,%s", x, y);
545}
546
547static void addEdgePos(Agedge_t *ep, attrs_t *alist, agxbuf *xb) {
548 if (!alist) return;
549 for (size_t i = 0; i < attrs_size(alist); ++i) {
550 gmlattr *const ap = attrs_get(alist, i);
551 if (ap->sort == POINT) {
552 addEdgePoint (ep, ap->u.lp, xb);
553 }
554 else {
555 fprintf (stderr, "non-point field in line attribute");
556 unknown ((Agobj_t*)ep, ap, xb);
557 }
558 }
559 agsafeset (ep, "pos", agxbuse (xb), "");
560}
561
562static void addEdgeGraphics(Agedge_t *ep, attrs_t *alist, agxbuf *xb,
563 agxbuf *unk) {
564 int cnt = 0;
565
566 for (size_t i = 0; alist != NULL && i < attrs_size(alist); ++i) {
567 gmlattr *const ap = attrs_get(alist, i);
568 if (ap->sort == WIDTH) {
569 agsafeset (ep, "penwidth", ap->u.value, "");
570 }
571 else if (ap->sort == STYLE) {
572 agsafeset (ep, "style", ap->u.value, "");
573 }
574 else if (ap->sort == FILL) {
575 agsafeset (ep, "color", ap->u.value, "");
576 }
577 else if (ap->sort == LINE) {
578 addEdgePos (ep, ap->u.lp, xb);
579 }
580 else {
581 if (cnt)
582 agxbputc (unk, ' ');
583 else {
584 agxbput (unk, "[ ");
585 }
586 deparseAttr (ap, unk);
587 cnt++;
588 }
589 }
590
591 if (cnt) {
592 agxbput (unk, " ]");
593 agsafeset (ep, "graphics", agxbuse (unk), "");
594 }
595 else
596 agxbclear(unk);
597}
598
599static void addAttrs(Agobj_t *obj, attrs_t *alist, agxbuf *xb, agxbuf *unk) {
600 for (size_t i = 0; i < attrs_size(alist); ++i) {
601 gmlattr *const ap = attrs_get(alist, i);
602 if (ap->sort == GRAPHICS) {
603 if (AGTYPE(obj) == AGNODE)
604 addNodeGraphics ((Agnode_t*)obj, ap->u.lp, xb, unk);
605 else if (AGTYPE(obj) == AGEDGE)
606 addEdgeGraphics ((Agedge_t*)obj, ap->u.lp, xb, unk);
607 else
608 unknown (obj, ap, xb);
609 }
610 else if (ap->sort == LABELGRAPHICS) {
611 if (AGTYPE(obj) == AGNODE)
612 addNodeLabelGraphics ((Agnode_t*)obj, ap->u.lp, unk);
613 else if (AGTYPE(obj) == AGEDGE)
614 addEdgeLabelGraphics ((Agedge_t*)obj, ap->u.lp, xb, unk);
615 else
616 unknown (obj, ap, xb);
617 }
618 else
619 unknown (obj, ap, xb);
620 }
621}
622
624 agxbuf *xb, agxbuf *unk) {
625 Agraph_t* g;
626 Agnode_t* n;
627 Agnode_t* h;
628 Agedge_t* e;
629
630 if (parent) {
631 g = agsubg (parent, NULL, 1);
632 }
633 else if (graph->directed >= 1)
634 g = agopen (name, Agdirected, 0);
635 else
636 g = agopen (name, Agundirected, 0);
637
638 if (!parent && L) {
639 addAttrs ((Agobj_t*)g, L, xb, unk);
640 }
641 for (size_t i = 0; i < nodes_size(&graph->nodelist); ++i) {
642 gmlnode *const np = nodes_get(&graph->nodelist, i);
643 if (!np->id) {
644 fprintf (stderr, "node without an id attribute");
645 graphviz_exit (1);
646 }
647 n = agnode (g, np->id, 1);
648 addAttrs((Agobj_t*)n, &np->attrlist, xb, unk);
649 }
650
651 for (size_t i = 0; i < edges_size(&graph->edgelist); ++i) {
652 gmledge *ep = edges_get(&graph->edgelist, i);
653 if (!ep->source) {
654 fprintf (stderr, "edge without an source attribute");
655 graphviz_exit (1);
656 }
657 if (!ep->target) {
658 fprintf (stderr, "node without an target attribute");
659 graphviz_exit (1);
660 }
661 n = agnode (g, ep->source, 1);
662 h = agnode (g, ep->target, 1);
663 e = agedge (g, n, h, NULL, 1);
664 addAttrs((Agobj_t*)e, &ep->attrlist, xb, unk);
665 }
666 for (size_t i = 0; i < graphs_size(graph->graphlist); ++i) {
667 gmlgraph *const gp = graphs_get(graph->graphlist, i);
668 mkGraph (gp, g, NULL, xb, unk);
669 }
670
671 addAttrs((Agobj_t*)g, &graph->attrlist, xb, unk);
672
673 return g;
674}
675
677gml_to_gv (char* name, FILE* fp, int cnt, int* errors)
678{
679 Agraph_t* g;
680 int error;
681
682 if (cnt == 0)
683 initgmlscan(fp);
684 else
685 initgmlscan(0);
686
687 L = NULL;
688 pushAlist ();
689 gmlparse ();
690
691 error = gmlerrors();
692 *errors |= error;
693 if (!G || error)
694 g = NULL;
695 else {
696 agxbuf xb = {0};
697 agxbuf unk = {0};
698 g = mkGraph (G, NULL, name, &xb, &unk);
699 agxbfree (&xb);
700 agxbfree(&unk);
701 }
702
703 cleanup ();
704
705 return g;
706}
707
708static char *sortToStr(unsigned short sort) {
709 char* s;
710
711 switch (sort) {
712 case GRAPH :
713 s = "graph"; break;
714 case NODE :
715 s = "node"; break;
716 case EDGE :
717 s = "edge"; break;
718 case DIRECTED :
719 s = "directed"; break;
720 case ID :
721 s = "id"; break;
722 case SOURCE :
723 s = "source"; break;
724 case TARGET :
725 s = "target"; break;
726 case XVAL :
727 s = "xval"; break;
728 case YVAL :
729 s = "yval"; break;
730 case WVAL :
731 s = "wval"; break;
732 case HVAL :
733 s = "hval"; break;
734 case LABEL :
735 s = "label"; break;
736 case GRAPHICS :
737 s = "graphics"; break;
738 case LABELGRAPHICS :
739 s = "labelGraphics"; break;
740 case TYPE :
741 s = "type"; break;
742 case FILL :
743 s = "fill"; break;
744 case OUTLINE :
745 s = "outline"; break;
746 case OUTLINESTYLE :
747 s = "outlineStyle"; break;
748 case OUTLINEWIDTH :
749 s = "outlineWidth"; break;
750 case WIDTH :
751 s = "width"; break;
752 case STYLE :
753 s = "style"; break;
754 case LINE :
755 s = "line"; break;
756 case POINT :
757 s = "point"; break;
758 case TEXT :
759 s = "text"; break;
760 case FONTSIZE :
761 s = "fontSize"; break;
762 case FONTNAME :
763 s = "fontName"; break;
764 case COLOR :
765 s = "color"; break;
766 case INTEGER :
767 s = "integer"; break;
768 case REAL :
769 s = "real"; break;
770 case STRING :
771 s = "string"; break;
772 case NAME :
773 s = "name"; break;
774 case LIST :
775 s = "list"; break;
776 case '[' :
777 s = "["; break;
778 case ']' :
779 s = "]"; break;
780 default :
781 s = NULL;break;
782 }
783
784 return s;
785}
static void agxbfree(agxbuf *xb)
free any malloced resources
Definition agxbuf.h:78
static int agxbprint(agxbuf *xb, const char *fmt,...)
Printf-style output to an agxbuf.
Definition agxbuf.h:234
static void agxbclear(agxbuf *xb)
resets pointer to data
Definition agxbuf.h:294
static WUR char * agxbuse(agxbuf *xb)
Definition agxbuf.h:307
static size_t agxblen(const agxbuf *xb)
return number of characters currently stored
Definition agxbuf.h:89
static int agxbputc(agxbuf *xb, char c)
add character to buffer
Definition agxbuf.h:277
Memory allocation wrappers that exit on failure.
static char * gv_strdup(const char *original)
Definition alloc.h:101
static void * gv_alloc(size_t size)
Definition alloc.h:47
#define parent(i)
Definition closest.c:80
static NORETURN void graphviz_exit(int status)
Definition exit.h:23
#define DIRECTED
Definition gc.c:48
#define G
Definition gdefs.h:7
GML-DOT converter
int gmlerrors(void)
Definition gmlscan.l:133
void initgmlscan(FILE *)
Definition gmlscan.c:849
void free_graph(gmlgraph *p)
Definition gmlparse.c:117
void free_node(gmlnode *p)
Definition gmlparse.c:105
void free_edge(gmledge *p)
Definition gmlparse.c:111
void gmllexeof(void)
Definition gmlscan.l:138
#define LABEL
Definition gmlparse.c:357
#define OUTLINESTYLE
Definition gmlparse.c:363
#define WIDTH
Definition gmlparse.c:365
#define GRAPHICS
Definition gmlparse.c:358
static void free_attrs(attrs_t *a)
Definition gmlparse.c:95
#define YYABORT
Definition gmlparse.c:973
#define POINT
Definition gmlparse.c:368
#define NAME
Definition gmlparse.c:377
static attrs_t * L
Definition gmlparse.c:93
#define COLOR
Definition gmlparse.c:372
static dts_t liststk
Definition gmlparse.c:101
#define TEXT
Definition gmlparse.c:369
#define TYPE
Definition gmlparse.c:360
static void cleanup(void)
Definition gmlparse.c:128
#define FONTSIZE
Definition gmlparse.c:370
#define FILL
Definition gmlparse.c:361
static gmlnode * mkNode(void)
Definition gmlparse.c:193
static int setDir(char *d)
Definition gmlparse.c:232
static gmledge * mkEdge(void)
Definition gmlparse.c:201
#define ID
Definition gmlparse.c:376
static void pushAlist(void)
Definition gmlparse.c:150
#define OUTLINEWIDTH
Definition gmlparse.c:364
static void popG(void)
Definition gmlparse.c:172
#define SOURCE
Definition gmlparse.c:351
int gmlparse(void)
#define NODE
Definition gmlparse.c:348
#define TARGET
Definition gmlparse.c:352
#define WVAL
Definition gmlparse.c:355
#define EDGE
Definition gmlparse.c:349
#define STYLE
Definition gmlparse.c:366
#define HVAL
Definition gmlparse.c:356
static gmlattr * mkAttr(char *name, unsigned short sort, unsigned short kind, char *str, attrs_t *list)
Definition gmlparse.c:209
#define YVAL
Definition gmlparse.c:354
#define FONTNAME
Definition gmlparse.c:371
#define LABELGRAPHICS
Definition gmlparse.c:359
#define LIST
Definition gmlparse.c:378
void free(void *)
#define XVAL
Definition gmlparse.c:353
static void pushG(void)
Definition gmlparse.c:178
#define LINE
Definition gmlparse.c:367
#define OUTLINE
Definition gmlparse.c:362
#define yyerror
Definition gmlparse.c:70
static attrs_t * popAlist(void)
Definition gmlparse.c:160
#define GRAPH
Definition gmlparse.c:347
static char * sortToStr(unsigned short sort)
Definition gmlparse.y:708
static void addEdgeGraphics(Agedge_t *ep, attrs_t *alist, agxbuf *xb, agxbuf *unk)
Definition gmlparse.y:562
static void addAttrs(Agobj_t *obj, attrs_t *alist, agxbuf *xb, agxbuf *unk)
Definition gmlparse.y:599
static void deparseAttr(gmlattr *ap, agxbuf *xb)
Definition gmlparse.y:332
alist $2
Definition gmlparse.y:284
static void addEdgeLabelGraphics(Agedge_t *ep, attrs_t *alist, agxbuf *xb, agxbuf *unk)
Definition gmlparse.y:411
void free_attr(gmlattr *p)
Definition gmlparse.y:319
glistitem $1
Definition gmlparse.y:239
alistitem NAME REAL
Definition gmlparse.y:289
static void addNodeLabelGraphics(Agnode_t *np, attrs_t *alist, agxbuf *unk)
Definition gmlparse.y:372
edge
Definition gmlparse.y:240
static Agraph_t * mkGraph(gmlgraph *graph, Agraph_t *parent, char *name, agxbuf *xb, agxbuf *unk)
Definition gmlparse.y:623
static void addNodeGraphics(Agnode_t *np, attrs_t *alist, agxbuf *xb, agxbuf *unk)
Definition gmlparse.y:462
static void addEdgePoint(Agedge_t *ep, attrs_t *alist, agxbuf *xb)
Definition gmlparse.y:525
static void addEdgePos(Agedge_t *ep, attrs_t *alist, agxbuf *xb)
Definition gmlparse.y:547
N
Definition gmlparse.y:253
E
Definition gmlparse.y:264
NAME STRING
Definition gmlparse.y:290
hdr body DIRECTED INTEGER
Definition gmlparse.y:242
static void deparseList(attrs_t *alist, agxbuf *xb)
Definition gmlparse.y:346
alistitem
Definition gmlparse.y:261
optalist
Definition gmlparse.y:277
NAME attrlist
Definition gmlparse.y:291
Agraph_t * gml_to_gv(char *name, FILE *fp, int cnt, int *errors)
Definition gmlparse.y:677
static int errors
Definition gmlscan.c:846
body
Definition grammar.y:197
node NULL
Definition grammar.y:163
static int cnt(Dict_t *d, Dtlink_t **set)
Definition graph.c:210
int agsafeset(void *obj, char *name, const char *value, const char *def)
ensures the given attribute is declared before setting it locally on an object
Definition attr.c:507
Agedge_t * agedge(Agraph_t *g, Agnode_t *t, Agnode_t *h, char *name, int createflag)
Definition edge.c:260
Agdesc_t Agundirected
undirected
Definition graph.c:286
Agraph_t * agopen(char *name, Agdesc_t desc, Agdisc_t *disc)
creates a new graph with the given name and kind
Definition graph.c:44
Agdesc_t Agdirected
directed
Definition graph.c:284
Agnode_t * agnode(Agraph_t *g, char *name, int createflag)
Definition node.c:145
#define AGTYPE(obj)
returns AGRAPH, AGNODE, or AGEDGE depending on the type of the object
Definition cgraph.h:216
@ AGEDGE
Definition cgraph.h:207
@ AGNODE
Definition cgraph.h:207
Agraph_t * agsubg(Agraph_t *g, char *name, int cflag)
Definition subg.c:58
Agraph_t * graph(char *name)
Definition gv.cpp:30
agxbput(xb, staging)
@ unknown
Definition gvgen.c:32
textitem scanner parser str
Definition htmlparse.y:224
table Syntax error
Definition htmlparse.y:294
$$
Definition htmlparse.y:327
#define DEFINE_LIST_WITH_DTOR(name, type, dtor)
Definition list.h:34
a generic header of Agraph_s, Agnode_s and Agedge_s
Definition cgraph.h:210
graph or subgraph
Definition cgraph.h:425
Definition types.h:251
union gmlattr::@58 u
void * lp
actually an attrs_t *
Definition gml2gv.h:16
char * value
Definition gml2gv.h:15
unsigned short kind
Definition gml2gv.h:11
unsigned short sort
Definition gml2gv.h:12
char * name
Definition gml2gv.h:13
char * source
Definition gml2gv.h:34
attrs_t attrlist
Definition gml2gv.h:36
char * target
Definition gml2gv.h:35
int directed
Definition gml2gv.h:45
struct gmlgraph * parent
Definition gml2gv.h:44
void * graphlist
actually a graphs_t *
Definition gml2gv.h:49
nodes_t nodelist
Definition gml2gv.h:47
attrs_t attrlist
Definition gml2gv.h:46
edges_t edgelist
Definition gml2gv.h:48
attrs_t attrlist
Definition gml2gv.h:26
char * id
Definition gml2gv.h:25
Definition grammar.c:93