Consider the grammer below: S -> Atoms Atoms -> epsilon Atoms -> Atom Atoms Atom
ID: 3915959 • Letter: C
Question
Consider the grammer below:
S -> Atoms
Atoms -> epsilon
Atoms -> Atom Atoms
Atom -> ' Atom
Atom -> List
Atom -> id
Atom -> int
List -> ( ListBody )
ListBody -> Atoms
1) As a Scheme program is being parsed, it is useful to generate a tree representation of the program, where the nodes in the tree are atoms, which can be integers, identiers, quotes, or lists. Both quote nodes and list nodes are internal nodes, while integers and identiers are leaf nodes. Suppose you were provided with the operations:
T < - leaf node(x) which creates a leaf node and stores the identier or integer x in the node.
T <- int node() which creates a new list (internal) node.
T <- add(n; T) which prepends node n to the children of node T and returns T.
Give a synthetic attribute grammar (S-Grammar) for the grammar above that will construct a tree representation of a program as it is being parsed using the provided grammar.
2) A Scheme program that does not dene its own functions can easily be evaluated as it is parsed. Assume you are provided with the function b <- eval(a) which takes an atom as a parameter, evaluates it, and returns the result of the evaluation, as an atom. If an error occurrs during evaluation, an error is raised. Extend the synthetic attribute grammar from Question 1 to an inherited attribute grammar (L-grammar) that evaluates the program as it is being parsed.. I.e., after an atom is parsed, it should be evaluated. Note: you will use the tree created by the attribute grammar from Question 1, but instead of the original atom a being stored, its evaluation eval(a) should be stored. Recall, that a quoted atom should not be evaluated, which is why an L-grammar, instead of an S-grammar is needed in this case.
Explanation / Answer
For part 1.
Link List Implementation in C
struct atomsNode
{
int val;
struct listNode * next;
};
typedef struct listNode item;0
Create a list of n elements //leaf node
item * curr, * head, *tail;
int i;
head = tail = NULL;
for(i=1;i<=10;i++)
{
curr = (item *)malloc(sizeof(item));
//allocate one item
curr->val = i;
curr->next = NULL;
if(head == NULL)
{
head = curr; tail = head;
}
Note: head is pointing to first ever node. Tail points to the last item else
{
tail->next = curr;
tail = tail->next;
}
}
Add an element to keep tree sorted
node * root = NULL;
//global
void insert(node * item)
{
if(root == NULL)
{
root it =em;
}
else
{ node * curr = root;
//curr is your reference that keeps moving while(1)
{
if(item->val < curr->val)
{
if(curr->left == NULL)
{
curr->left = item;
break;
}
else
{ curr = curr->left;
}
}