9 #define INFTY 100000000
14 struct node *first_son;
15 struct node *next_sibling;
16 struct node *backlink; /* We use them only for internal nodes */
17 char *label; /* Label of edge above this node */
25 static void dump_tree(struct node *n, int level, char *strend)
27 printf("%-3d ", n->id);
28 for (int i=0; i<level; i++)
30 printf("<%.*s%s> {%d}\n",
31 (n->lablen >= INFTY/2 ? (int)(strend-n->label) : n->lablen), n->label,
32 (n->lablen >= INFTY/2 ? "*" : ""), n->backlink ? n->backlink->id : -1);
33 for (n=n->first_son; n; n=n->next_sibling)
34 dump_tree(n, level+1, strend);
38 static struct node *new_node(void)
40 struct node *n = malloc(sizeof(*n));
49 static struct node *lookup_edge(struct node *x, int c, struct node ***ptr_from)
51 struct node **f = &x->first_son;
56 if (x->label[0] == c) {
64 static struct node *build_tree(char *string)
66 struct node *root = new_node();
67 struct node *l = root; /* Currently longest nested suffix as a canonical reference pair (node, label) */
68 char *llabel = string;
70 struct node *x, *y, *z, *trash, **blp, **from;
72 for (int i=0; string[i]; i++) {
75 while (llablen) { /* Canonicalize the reference pair */
76 x = lookup_edge(l, llabel[0], &from);
77 if (x->lablen > llablen)
83 if (!llablen) { /* LNS is an internal node or root */
86 if (lookup_edge(l, string[i], &from)) { /* Found LNS for the new string */
92 z->next_sibling = l->first_son;
94 } else { /* LNS is in the middle of an edge */
95 x = lookup_edge(l, llabel[0], &from);
96 if (x->label[llablen] == string[i]) { /* found LNS for the new string */
100 y = new_node(); /* New interior node inside the edge */
101 z = new_node(); /* New leaf connected below x */
103 y->next_sibling = x->next_sibling;
106 x->next_sibling = NULL;
110 x->lablen -= llablen;
112 blp = &y->backlink; /* Backlink will be filled in later */
117 if (l == root) { /* Cut the first character of the LNS */
137 struct node *root = build_tree(x);
139 dump_tree(root, 0, x+strlen(x));