Notes for Discussion March 18, 1998

by Andrew LoPucki - lopucki@cs.wisc.edu



Professor Fisher issued a handout on the erroneous syntax error message that is sometimes given by proj3( by the main() method.) The problem is caused because the parser may get an exception thrown by some production code we entered. It then throws it, eventually, back to the calling program. Details on the problem are in the handout. The handout was also sent to the mailing list so everyone should already have seen this.


Questions from students:


Review of the handout

Again, see the handout(or email) for a complete description of what is there.




Another Problem: memberdecls

How to build ASTs? First lets look at a good one(a logical one.)

	STMTS	------>	STMT  STMTS

In java cup we refer to the right hand side parts with STMT:a and STMTS:b. In Yacc they are reference by $1 and $2. Either way we first look at the left hand side of the production to see what kind of node to build for the AST. In this case we build a stmtsNode. A stmtsNode requires that we give its constructor a stmtNode and another stmtsNode. That's convenient because in this case we are given both by 'a' and 'b' (or $1 and $2 in Yacc.)

But what about the memberdecls production? It looks like this:

	memberdecls	------>	fielddecl:f  memberdecls:m
			|	methoddecls:m

Now if we look at the left hand side we see we need to create a memberdeclsNode. But if we look at the constructor it requires a fielddeclsNode (NOT a fielddeclNode) and also a methoddeclsNode, which may not be available because in the first production we have another memberdeclsNode. It seems like the construction should be:

	memberdecls	------>	fielddecls:f  methoddecls:m

But this causes an unforseen problem, and is in fact the way it was written when Professor Fischer first wrote out the language. The problem is that if we read an INT it could be part of a fielddecl or it might be a return type for a methoddecl. So we are forced to change the logic.

A two part construction is recommended for the building of this production's AST node. First, though, do the production for the second production (ie. methoddecls.) Create a memberdeclsNode with the methoddecls given by 'm' and a nullNode of the appropriate type for the fielddecls part. Now for the first production, create fielddeclsNode out of the fielddeclNode given by 'f' and the fielddeclsNode of the memberdecls. Reassign the fielddeclsNode of the memberdeclsNode that we have so that it now 'points' to the new fielddeclsNode we just created. And now we're done.

One way of looking at this is to think of it as taking a memberdeclsNode and dereferencing the fielddeclsNode it had and moving that pointer to the new fieldDeclsNode we created. This should take 2 or 3 instructions.


One last thing - the dangling else problem

The problem is that we have an ambiguity problem with the current production list for STMT:

	STMT	------>	If  Expr  STMT
		|	If  Expr  STMT  Else  STMT
		|	Other

Visually it should work like this:

But the definition we actually have allows this interpretation also:

This picture makes it obvious that we have to do something else, because the else should obviously be associated with the nearest if.

We could create a 'restricted stmt' in order to deal with this. Our new production would look something like this:

	STMT	------>	If  E  STMT
		|	If  E  RSTMT  ELSE  STMT
		|	Other

	RSTMT	------>  Any STMT except the IF THEN (including: IF  E  RSTMT  ELSE  RSTMT)

* Now we must also do something similar to protect the while statement.



* NOTE: Some have used precedence to solve this problem. It is ok to do that BUT you must explain carefully and thoroughly how it works.

*Extra credit - Any error recovery at all will get extra credit.