8 struct node *first_son;
9 struct node *next_sibling;
10 struct node *backlink; /* We use them only for internal nodes */
11 char *label; /* Label of edge above this node */
15 static void dump_tree(struct node *n, int level, char *strend)
17 for (int i=0; i<level; i++)
19 printf("<%.*s%s> [%p] {%p}\n",
20 (n->lablen >= INFTY/2 ? strend-n->label : n->lablen), n->label,
21 (n->lablen >= INFTY/2 ? "*" : ""), n, n->backlink);
22 for (n=n->first_son; n; n=n->next_sibling)
23 dump_tree(n, level+1, strend);
26 static struct node *new_node(void)
28 struct node *n = malloc(sizeof(*n));
33 static struct node *lookup_edge(struct node *x, int c)
36 while (x && x->label[0] != c)
41 static struct node *build_tree(char *string)
43 struct node *root = new_node();
44 struct node *l = root; /* Currently longest nested suffix as a canonical reference pair (node, label) */
45 char *llabel = string;
47 struct node *x, *y, *z, *trash, **blp;
49 for (int i=0; string[i]; i++) {
52 while (llablen) { /* Canonicalize the reference pair */
53 x = lookup_edge(l, llabel[0]);
54 if (x->lablen > llablen)
60 if (!llablen) { /* LNS is an internal node or root */
63 if (lookup_edge(l, string[i])) { /* Found LNS for the new string */
69 z->next_sibling = l->first_son;
71 } else { /* LNS is in the middle of an edge */
72 x = lookup_edge(l, llabel[0]);
73 if (x->label[llablen] == string[i]) { /* found LNS for the new string */
77 y = new_node(); /* New interior node which gets all sons of x */
78 z = new_node(); /* New leaf connected below x */
79 y->first_son = x->first_son;
80 y->next_sibling = NULL;
81 y->backlink = x->backlink;
82 y->label = x->label + llablen;
83 y->lablen = x->lablen - llablen;
87 blp = &x->backlink; /* Backlink will be filled in later */
94 if (l == root) { /* Cut the first character of the LNS */
107 int main(int argc, char **argv)
109 char *string = argv[1];
110 struct node *root = build_tree(string);
112 dump_tree(root, 0, string+strlen(string));