SE250:lab-8:jsmi233

From Marks Wiki
Jump to navigation Jump to search

Lab 8: Parse Tree’s

This failed:

ParseTree* t = mkNode('-', mkNode( '(', mkNode('-', mkNode( '(', mkNode('a', 'b', 0), ')', 0 ), 0 ), ')', 0 ), 0 );


This worked:

ParseTree* t = mkNode( '-', mkNode( '-', mkNode( 'a', 0 ), mkNode( 'b', 0 ), 0 ), 0);


After a long time which made me think there must be an easier way to do this, I got this code to make the ternary statement:

 ParseTree* a = mkNode('?', mkNode('=', mkNode('a', 0), mkNode('2', 0), 0), mkNode('-', mkNode('x', 0), mkNode('y', 0), 0), mkNode('-', mkNode('y', 0), mkNode('x', 0), 0), 0);
 ParseTree* b = mkNode('>', mkNode('+', mkNode('a', 0), mkNode('b', 0), 0), mkNode('c', 0), 0);
 ParseTree* c = mkNode('*', mkNode('z', 0), mkNode('+', mkNode('y', 0), mkNode('b', 0), 0), 0);
 ParseTree* t = mkNode('?', b, c, a, 0); 


The picture of the tree looked the way I expected. The mkNode syntax makes it fairly obvious I think.


In C, the colon separates the second and third argument. However the tree doesn’t need an extra character to do this job because it the second and third argument correspond to the second and third child.


This is my first attempt at eval with no error checking:

 int eval(ParseTree *node) {
 	switch (node->name) {
 		case '+':
 			return eval(node->arg[0]) + eval(node->arg[1]);
 		case '-':
 			return eval(node->arg[0]) - eval(node->arg[1]);
 		case '*':
 			return eval(node->arg[0]) * eval(node->arg[1]);
 		case '/':
 			return eval(node->arg[0]) / eval(node->arg[1]);
 	}
 	return node->name - '0';
 }


Now to handle division by zero:

int eval(ParseTree *node) {
	int denom;
	switch (node->name) {
		case '+':
			return eval(node->arg[0]) + eval(node->arg[1]);
		case '-':
			return eval(node->arg[0]) - eval(node->arg[1]);
		case '*':
			return eval(node->arg[0]) * eval(node->arg[1]);
		case '/':
			denom = eval(node->arg[1]);
			if (denom == 0) { //Division by zero
				error("Division by zero!");
				return 0;
			}
			return eval(node->arg[0]) / denom;
	}
	return node->name - '0';
}


Which prevents the program from crashing (is that a good thing?) but returns an incorrect value. Furthermore, it is possible that several division by zero’s could occur in the same calculation, which is weird. What I would like is a way to stop all the eval functions as soon as an error occurs.