CS 410 Programming Assignment 2: Clarifications, Corrections, and Hints

Fall 2006 [Bono]

[9/22/06 CMB] Correction: A better link to Java operator precedence rules

The bad thing about using web references is that they can change or disappear. The contents of the page I referred you to for a operator precedence rules for Java has changed out from under us, and it doesn't appear that there is another summary at that same site (Sun Java Tutorial). That out-of-date link was given in the assignment description and on the course web page.

There are many places to get this information on the web. I'm going to give you one link which may not be long-lived, but should be good until the due date for PA2 this semester. It's from a work-in-progress manuscript by Bill Venners called Objects and Java found on the artima.com web site. Once you follow the link you should tell your browser to search for the term precedence, and you'll get to the section on Operator Precedence and Associativity.


[modified 2/14/06 CMB] Hint: How to fix shift-reduce conflict about stmtList and localList

When you add the part of the grammar for assignment statements, you might start getting a shift-reduce conflict that involves the state that has the following two items in it (this state also has other stuff I'm leaving out here):
localList  ->  localList . local
method --> type ID (formalList) { localList . stmtList RETURN expr ; }
The shift-reduce conflict is on ID, where it doesn't know whether to reduce by
 stmtList --> <eps> 
(i.e., the RHS is epsilon, the empty string) or to shift ID, to start building the next local declaration. (Note that both local decls and assgt statements can start with ID, but this isn't an inherent problem for us if we write the grammar correctly.) There would be a similar conflict for the rule for mainMethod.

We only want the top-level stmtList to go to epsilon if there are NO statements in the method we are parsing. But both ID and RETURN are in FOLLOW(stmtList), so the parser can reduce on ID, or shift on ID (because a local can start with an ID). We can fix this so that we only use an eps-production if it's actually an empty statement list. We can do this by writing the grammar to distinguish an empty statement list from a non-empty statement list. Then we only use the epsilon production for the statement list if the whole statement list is empty (an empty statement list can only be followed by '}' or RETURN, not ID, so the conflict goes away). There are two possible parts of the grammar you can change to do this:

One solution involves changing the stmtList grammar so that it distinguishes an empty stmtList from a non-empty stmtList. We only use an eps-prod if there is an empty statement list, and we'll have another non-terminal for a sequence of one or more statements. This new non-terminal will have no epsilon-production.

An alternate way to achieve the same effect is to change the rules for method and mainMethod instead, so that each of them distinguish the empty statement list case from non-empty statement list case.


[10/7/04 CMB] Hint: "I ran my parser and it crashed, what do I do?"

"Bus error" is a run-time error on unix (another one is "segmentation fault"). These are usually caused by a dangling pointer, or accessing through a NULL pointer, or array bounds problems.

My guess is that for one of your trees you didn't assign anything meaningful for one of the subtrees, then when dump went to print it, it's trying to dereference an invalid or NULL pointer. So, in this scenario crashing from a dump routine doesn't mean dump is broken. Also sometimes run-time errors happen in a different place than what actually caused the error, because if you have overwritten a random part of memory, you can get bad values in places you don't expect. That said, you probably will be able to find where the problem is by running a symbolic debugger: ddd or gdb work with g++-compiled programs. If you run it in the debugger it will show you the source line where it crashed, and you can start examining the call sequence to there, etc.

If you are unfamiliar with the debuggers: you can run gdb from inside emacs

esc-x gdb
then it will prompt for the exe (testparser)

when the gdb prompt comes up in an emacs window type

run Test.esp
(or give whatever prog you were trying it on)

then it will crash and point a cursor at the right line number in a different emacs window. You can then do the

where
command in gdb to see what's on the call stack, and then navigate around the call stack if necessary using the commands up and down E.g., if it was doing dump on a particular type of node when it crashed, you should focus on your bison code that creates that node. The command help is how you get help in gdb. There is also a slightly longer introduction to debugging in Unix linked in the Documentation section of the web page.

[10/6/04 CMB] Hint: strategies for diagnosing unexpected parse errors

By parse errors here, I mean you gave what you thought was a correct Espresso program for your subset, but your parser tells you there is a parse error. Here are some things you can try:

The University of Southern California does not screen or control the content on this website and thus does not guarantee the accuracy, integrity, or quality of such content. All content on this website is provided by and is the sole responsibility of the person from which such content originated, and such content does not necessarily reflect the opinions of the University administration or the Board of Trustees