|
|
1.1 ! root 1: %{ ! 2: #include "draw_dag.h" ! 3: #include "dag.h" ! 4: #define MIN_RANK_SEP 4 ! 5: ! 6: static pair_t* nodelist; ! 7: static DAG_edge_t* this_edge; ! 8: static boolean is_ordered = false; ! 9: ! 10: int Syntax_error; ! 11: DAG_node_t Reset_node,Default_node,Proto_node; ! 12: DAG_edge_t Reset_edge,Default_edge; ! 13: static boolean set_pointsize,set_label,set_shape,set_color,set_xsize,set_ysize; ! 14: ! 15: static void teardown (pair_t *e) { ! 16: pair_t *f; ! 17: while (e) { ! 18: f = e->next; ! 19: delete e; ! 20: e = f; ! 21: } ! 22: } ! 23: ! 24: static void init_proto() { ! 25: Proto_node = Default_node; ! 26: set_pointsize = set_label = set_shape = set_color = set_xsize = set_ysize = false; ! 27: } ! 28: ! 29: static void apply_proto(DAG_node_t *np) { ! 30: /* label setting has precedence over size! */ ! 31: if (set_pointsize) np->setpointsize(Proto_node.pointsize); ! 32: if (set_label) np->setlabel(Proto_node.label.type,Proto_node.label.value); ! 33: if (set_shape) np->setshape(Proto_node.shape.type,Proto_node.shape.value); ! 34: if (set_color) np->setcolor(Proto_node.color); ! 35: if (set_xsize) np->setxsize(Proto_node.xsize); ! 36: if (set_ysize) np->setysize(Proto_node.ysize); ! 37: np->autosize(); ! 38: } ! 39: ! 40: static void install_proto() { ! 41: Proto_node.autosize(); ! 42: for (pair_t* p = nodelist; p; p = p->next) ! 43: apply_proto(Node[p->node]); ! 44: } ! 45: ! 46: /* append list1 to list2 */ ! 47: static DAG_edge_t* append(DAG_edge_t *list1, DAG_edge_t *list2) { ! 48: if (!list2) panic("null list2"); ! 49: DAG_edge_t *e,*f; ! 50: e = list2; ! 51: while (f = e->nextof()) e = f; ! 52: e->next = (edge_t*) list1; ! 53: return list2; ! 54: } ! 55: ! 56: /* create a new set of same rank nodes within the Options struct */ ! 57: static int* &newset() { ! 58: const int hunksize = 16; ! 59: if (!Options.same_nodes) ! 60: Options.same_nodes = new int*[hunksize]; ! 61: else if (!(Options.n_same_nodes % hunksize)) ! 62: Options.same_nodes = (int**)realloc((char*)Options.same_nodes, ! 63: (Options.n_same_nodes + hunksize + 1)*sizeof(int*)); ! 64: Options.same_nodes[Options.n_same_nodes] = 0; ! 65: return(Options.same_nodes[Options.n_same_nodes++]); ! 66: } ! 67: ! 68: /* take the union of same rank nodes */ ! 69: overload set_union; ! 70: static void set_union (int* &ptr, pair_t *nlist) { ! 71: pair_t *e; ! 72: int olen = 0, nlen = 0; ! 73: for (e = nlist; e; e = e->next) nlen++; ! 74: if (!nlen) return; ! 75: if (ptr) { ! 76: while (ptr[olen++] >= 0); ! 77: ptr = (int*)realloc((char*)ptr,(nlen+olen)*sizeof(int)); ! 78: } ! 79: else ptr = new int[nlen + 1]; ! 80: ! 81: for (e = nlist; e; e = e->next) ! 82: ptr[olen++] = e->node; ! 83: ptr[olen] = -1; ! 84: } ! 85: ! 86: static void set_union(int* &ptr, DAG_edge_t *elist) { ! 87: pair_t *p = 0; ! 88: while (elist) { ! 89: p = new pair_t(elist->node,p); ! 90: elist = elist->nextof(); ! 91: } ! 92: set_union(ptr,p); ! 93: teardown(p); ! 94: } ! 95: ! 96: static void make_invis_edge(int fromnode,int tonode) { ! 97: DAG_edge_t *e = new DAG_edge_t(); ! 98: e->ink = invis_ink; ! 99: e->node = tonode; ! 100: e->next = Edge[fromnode]; ! 101: Edge[fromnode] = e; ! 102: } ! 103: ! 104: static void enter_edgelist(int tailnode, DAG_edge_t* elist) { ! 105: DAG_edge_t *e; ! 106: if (is_ordered) { ! 107: set_union(newset(),elist); ! 108: for (e = elist; e->nextof(); e = e->nextof()) ! 109: make_invis_edge(e->node,e->nextof()->node); ! 110: is_ordered = false; ! 111: } ! 112: Edge[tailnode] = append(Edge[tailnode],elist); ! 113: } ! 114: ! 115: static void enter_backedgelist(int headnode, DAG_edge_t* elist) { ! 116: DAG_edge_t *e = elist; ! 117: while (e) { ! 118: DAG_edge_t *f = e->nextof(); ! 119: e->next = 0; ! 120: e->flipped = true; ! 121: int tailnode = e->node; ! 122: e->node = headnode; ! 123: Edge[tailnode] = append(Edge[tailnode],e); ! 124: e = f; ! 125: } ! 126: } ! 127: ! 128: static void enter_pathlist(int tailnode, DAG_edge_t* elist) { ! 129: DAG_edge_t *e,*f; ! 130: e = elist; ! 131: while (e) { ! 132: f = e; ! 133: e = e->nextof(); ! 134: f->next = Edge[tailnode]; ! 135: Edge[tailnode] = f; ! 136: tailnode = f->node; ! 137: } ! 138: is_ordered = false; ! 139: } ! 140: ! 141: static void enter_backpathlist(int headnode, DAG_edge_t *elist) { ! 142: DAG_edge_t *e = elist; ! 143: while (e) { ! 144: DAG_edge_t *f = e->nextof(); ! 145: e->next = 0; ! 146: e->flipped = true; ! 147: int tailnode = e->node; ! 148: e->node = headnode; ! 149: Edge[tailnode] = append(Edge[tailnode],e); ! 150: e = f; ! 151: headnode = tailnode; ! 152: } ! 153: } ! 154: ! 155: %} ! 156: %union { ! 157: char *s; ! 158: int i; ! 159: pair_t *p; // for node lists ! 160: DAG_edge_t *e; // for edge lists ! 161: } ! 162: %token <i> AS BACKEDGE BACKPATH COLOR DASHED DOTTED DRAW EDGE EDGES EQUALLY ! 163: %token <i> EXACTLY FROM HEIGHT INVIS LABEL MAXIMUM MINIMUM NODES ORDERED ! 164: %token <i> PATH POINTSIZE RANK RANKS SAME SEPARATE SOLID TO WEIGHT WIDTH ! 165: %token <s> STRING DESC ! 166: %type <i> nitem eitem inkval nname intval tailnode ! 167: %type <e> head_list head tohead ! 168: %type <p> nlist ! 169: %% ! 170: program : stmtlist ! 171: {make_drawing();} ! 172: | error ! 173: ; ! 174: ! 175: stmtlist : stmtlist stmt ! 176: | /*empty*/ ! 177: ; ! 178: ! 179: stmt : drawstmt ! 180: | edgestmt ! 181: | ctlstmt ! 182: ; ! 183: ! 184: drawstmt : DRAW nlist {init_proto(); nodelist = $2;} ndesc ';' ! 185: {install_proto(); teardown($2);} ! 186: | DRAW NODES {init_proto(); nodelist = 0;} ndesc ';' ! 187: {apply_proto(&Default_node);} ! 188: | DRAW EDGES {this_edge = &Default_edge;} edesc ';' ! 189: ; ! 190: ! 191: nlist : nlist nname ! 192: {$$ = new pair_t($2,$1);} ! 193: | nlist ',' nname ! 194: {$$ = new pair_t($3,$1);} ! 195: | nname ! 196: {$$ = new pair_t($1,(pair_t*)0);} ! 197: ; ! 198: ! 199: ! 200: ndesc : nitem ! 201: | ndesc nitem ! 202: ; ! 203: ! 204: nitem : WIDTH STRING ! 205: { ! 206: Proto_node.setxsize((int)(Resolution*atof($2))); ! 207: set_xsize = true; ! 208: } ! 209: ! 210: | HEIGHT STRING ! 211: { ! 212: Proto_node.setysize((int)(Resolution*atof($2))); ! 213: set_ysize = true; ! 214: } ! 215: | POINTSIZE intval ! 216: { ! 217: Proto_node.setpointsize($2); ! 218: set_pointsize = true; ! 219: } ! 220: | LABEL STRING ! 221: { ! 222: Proto_node.setlabel(STRING,$2); ! 223: set_label = true; ! 224: } ! 225: | LABEL DESC ! 226: { ! 227: Proto_node.setlabel(DESC,$2); ! 228: set_label = true; ! 229: } ! 230: | AS DESC ! 231: { ! 232: Proto_node.setshape(DESC,$2); ! 233: set_shape = true; ! 234: } ! 235: | AS STRING ! 236: { ! 237: Proto_node.setshape(STRING,$2); ! 238: set_shape = true; ! 239: } ! 240: | COLOR STRING ! 241: { ! 242: Proto_node.setcolor($2); ! 243: set_color = true; ! 244: } ! 245: ; ! 246: ! 247: edgestmt : ORDERED {is_ordered = true;} plainedgestmt ! 248: | plainedgestmt ! 249: ; ! 250: ! 251: plainedgestmt : nname ';' ! 252: | nname head_list ';' ! 253: {enter_edgelist($1,$2);} ! 254: | EDGE tailnode head_list ';' ! 255: {enter_edgelist($2,$3);} ! 256: | BACKEDGE tailnode head_list ';' ! 257: {enter_backedgelist($2,$3);} ! 258: | PATH tailnode head_list ';' ! 259: {enter_pathlist($2,$3);} ! 260: | BACKPATH tailnode head_list ';' ! 261: {enter_backpathlist($2,$3);} ! 262: | ';' /* empty statement */ ! 263: ; ! 264: ! 265: tailnode : nname ! 266: | FROM nname ! 267: {$$ = $2;} ! 268: ! 269: head_list : tohead ! 270: | head_list tohead ! 271: {$$ = append($2,$1);} ! 272: | head_list ',' tohead ! 273: {$$ = append($3,$1);} ! 274: ; ! 275: ! 276: tohead : head ! 277: | TO head ! 278: {$$ = $2;} ! 279: ; ! 280: ! 281: head : nname ! 282: { ! 283: this_edge = new DAG_edge_t(); ! 284: *this_edge = Default_edge; ! 285: this_edge->node = $1; ! 286: } ! 287: edesc ! 288: {$$ = this_edge;} ! 289: | nname ! 290: { ! 291: this_edge = new DAG_edge_t(); ! 292: *this_edge = Default_edge; ! 293: this_edge->node = $1; ! 294: $$ = this_edge; ! 295: } ! 296: ; ! 297: ! 298: edesc : eitem ! 299: | edesc eitem ! 300: ; ! 301: ! 302: eitem : WEIGHT intval ! 303: {this_edge->setweight($2);} ! 304: | LABEL DESC ! 305: {this_edge->setlabel(DESC,newstring($2));} ! 306: | LABEL STRING ! 307: {this_edge->setlabel(STRING,newstring($2));} ! 308: | POINTSIZE intval ! 309: {this_edge->setpointsize($2);} ! 310: | COLOR STRING ! 311: {this_edge->setcolor(newstring($2));} ! 312: | inkval ! 313: {this_edge->setink($1);} ! 314: ; ! 315: ! 316: ctlstmt : SEPARATE seplist ';' ! 317: | MINIMUM RANK nlist ';' ! 318: {set_union(Options.source_nodes,$3);teardown($3);} ! 319: | MAXIMUM RANK nlist ';' ! 320: {set_union(Options.sink_nodes,$3);teardown($3);} ! 321: | SAME RANK nlist ';' ! 322: {set_union(newset(),$3);teardown($3);} ! 323: ; ! 324: ! 325: seplist : seplist sepitem ! 326: | /* empty */ ! 327: ; ! 328: ! 329: sepitem : NODES STRING ! 330: { ! 331: Options.nodesep = max(1,round(Resolution*atof($2))); ! 332: } ! 333: | RANKS STRING EXACTLY ! 334: { ! 335: Options.ranksep = max(MIN_RANK_SEP,round(Resolution*atof($2))); ! 336: Options.rankadjust = 2; ! 337: } ! 338: ! 339: | RANKS STRING EQUALLY ! 340: { ! 341: Options.ranksep = max(MIN_RANK_SEP,round(Resolution*atof($2))); ! 342: Options.rankadjust = 1; ! 343: } ! 344: | RANKS EQUALLY ! 345: { ! 346: Options.rankadjust = 1; ! 347: } ! 348: | RANKS STRING ! 349: { ! 350: Options.ranksep = max(MIN_RANK_SEP,round(Resolution*atof($2))); ! 351: } ! 352: ; ! 353: ! 354: inkval : SOLID ! 355: {$$ = solid_ink;} ! 356: | DASHED ! 357: {$$ = dashed_ink;} ! 358: | DOTTED ! 359: {$$ = dotted_ink;} ! 360: | INVIS ! 361: {$$ = invis_ink;} ! 362: ; ! 363: ! 364: nname : STRING ! 365: {$$ = node_lookup($1);} ! 366: ; ! 367: ! 368: intval : STRING ! 369: {$$ = atoi($1);} ! 370: ;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.