Laboratory 8 FLT (Eng)
Laboratory 8 FLT (Eng)
The eighth laboratory consists of creating a lexico-syntactic analyzer to process binary search
trees in Haskell syntax, and comparatively, in ML syntax. The ML part will appear on a light blue
background. For the implementation we will choose one of the two syntaxes. We will consider
reading the trees and executing some operations on them: insert (inserting a node in a binary
tree) and count (counting the nodes of a tree, different from empty leaves Lf).
Examples of input in Haskell:
Node Lf 2 Lf
> Node Lf 2 Lf
As we can notice in the examples, the Haskell syntax of a binary tree is the following:
Node (Tree Int) Int (Tree Int)
And the ML syntax of a binary tree is: Node (int, int Tree, int Tree)
Let us take the binary tree from the following image as an example:
In order to represent binary search trees in memory, we will create a structure with three
members: one for the node key (of type int) and two for the node’s children (pointers to left
subtree and right subtree).
There will coexist two types on the value stack: int, for numbers read from the input and for
nodes’ keys, and a structure of type tree, for reducing numbers from the input to trees in the
right format (by reducing the right-hand side of productions to the left-hand side). So, yylval will
be a union with two members:
%union {
int ival;
struct _node *btree;
}
Regarding the set of productions, we will first have a set of rules (expr) that describe the input.
We can separate instructions from the input in two categories, by the result type. The trees
reading and the insert instruction both return trees, while the count instruction returns an
integer. So, we will have two sets of rules, one for the situations resulting in a tree (t_expr) and
one for those resulting in integers (i_expr). The most important set of rules is the one describing
how a binary tree is constructed (tree) using two Haskell/ML data constructors for binary trees:
the Node constructor with three arguments and the Lf constructor with zero arguments.
The set of productions for Haskell syntax:
expr : i_expr
| t_expr
;
i_expr : COUNT t_expr
|'(' i_expr ')'
| NUMBER
;
t_expr : INSERT i_expr t_expr
| '(' t_expr ')'
| tree
;
tree : NODE tree NUMBER tree
| '(' tree ')'
| LF
;
expr : i_expr
| t_expr
;
i_expr : COUNT '(' t_expr ')'
| NUMBER
;
t_expr : INSERT '(' i_expr ',' t_expr ')'
| tree
;
tree : NODE '(' NUMBER ',' tree ',' tree ')'
| LF
;
Proposed exercises:
1. Implement a function that searches for a number in a tree.
Examples in Haskell:
find 12 (Node (Node Lf 2 Lf) 10 (Node Lf 12 Lf))
> true
find 17 (Node (Node Lf 2 Lf) 10 (Node Lf 12 Lf))
> false
Examples in ML:
find(12, Node(10, Node(2, Lf, Lf), Node(12, Lf, Lf)))
> true
find(17, Node(10, Node(2, Lf, Lf), Node(12, Lf, Lf)))
> false
2. Implement a function that deletes a node from a tree. Check first if the node exists.
Example in Haskell:
delete 12 (Node (Node Lf 2 Lf) 10 (Node Lf 12 Lf))
> Node (Node Lf 2 Lf) 10 Lf
Example in ML:
delete(12, Node(10, Node(2, Lf, Lf), Node(12, Lf, Lf)))
> Node(10, Node(2, Lf, Lf), Lf)