An (incomplete) solution to Assignment #1 Programming Languages Course G22.2110-001 Spring 2000 --- Problem 1: ========== Sethi 2.12: To be done. ---------- Sethi 2.19: ----------- As explained during the course, here is a solution: S ::= if E then S | T T ::= if E then T else S To be able to work out examples, one should complete the grammar with (for instance) a basic token (say `x') for the non-terminal S, and `é for non-terminal E as: E ::= e S ::= if E then S | T T ::= if E then T else S | x You can then try to build a parse tree for: if e then if e then x else x ^ ^ T T ^ S ^^^^^^^^^^^^^^^^^^ T ^ ^ E S ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ S ------------------------------------------------------------------------- Problem 3: ========== The substr function, with lots of comments. A full program (usable for testing) can be found here. int substr(char *pat, char *str) { char *patf = pat, *strf = str; /* We maintain one "finger" patf on pat, and another one strf on str */ int index = 0; if (!(*pat)) return 0; /* We consider that the empty pattern always matches */ while (*pat && *str) { /* We superpose pat and str, and move the "fingers" on pat and str as long as they are on two equal chars */ while (*patf && *strf && (*patf == *strf)) { ++patf; ++strf; } if (*patf) /* We did not reach the end of pat: no match yet */ if (*strf) { /* Not yet at the end of str: we can continue */ strf = ++str; patf = pat; ++index; } else /* We are at the end of the string: no chance to get a match */ return -1; else /* We are at the end of the pattern: we got a match */ return index; } return -1; } --------------------------------------------------------------------------- Problem 4: ========== A full program is here. Type definition: ---------------- typedef struct node { int val; struct node *left, *right; } *bstree; It is always a good idea to have an allocation/initialization function for our dynamic data structures: bstree mknode(int v, bstree l, bstree r) { bstree tmp; tmp = (bstree) malloc(sizeof(struct node)); if (tmp == NULL) { fprintf(stderr, "Fatal error: memory allocation failed\n"); exit(1); } tmp->val = v; tmp->left = l; tmp->right=r; return tmp; } Adding an integer to the bs-tree: --------------------------------- bstree add(int v, bstree t) { if (t == NULL) return mknode(v, NULL, NULL); if (v < t->val) t->left = add(v, t->left); else if (v > t->val) t->right = add(v, t->right); return t; } Deleting an integer from a bstree: ---------------------------------- bstree delete(int v, bstree t) { if (t == NULL) return t; if (v < t->val) { t->left = delete(v, t->left); return t; } if (v > t->val) { t->right = delete(v, t->right); return t; } /* We are on the node that we want to delete */ if (t->right == NULL) return t->left; if (t->right->left == NULL) { bstree tmp = t->right; t->val = tmp->val; t->right = tmp->right; free(tmp); return t; } /* General case */ { /* We know that the right subtree exists, and that it has a left branch: wo go down that branch to get the leftmost node */ bstree tmp, ptr = t->right; while (ptr->left->left != NULL) ptr = ptr->left; tmp = ptr->left; ptr->left = tmp->right; t->val = tmp->val; free(tmp); return t; } } Listing in increasing order the elements: ----------------------------------------- void list(bstree t) { if (t == NULL) return; list(t->left); printf("%d ", t->val); list(t->right); } ===========================================================================