[comp.lang.c] Solved!

bobg+@andrew.cmu.edu (Robert Steven Glickstein) (06/23/89)

In: 21-Jun-89 Yacc probs w/ANSI-C, I wrote

> I've written a parser for ANSI-C using YACC (adhering strictly to the
> grammar given in K&R, second edition) that doesn't work.  Despite the
> claim in section A13 that "this grammar is acceptable to the YACC
> parser-generator"(modulo some changes, which I've made), it in fact is
not; it's not even LR(1).

My profuse apologies to Messrs. Kernighan and Ritchie.  I had failed to
follow the advice given in section A13 that tells the Yacc user to write
all rules containing optional subrules twice.  That is to say, I had
written

    foo: bar opt_baz bletch
        ;
    opt_baz:
        | baz
        ;

when I should have written

    foo: bar bletch
        | bar baz bletch
        ;

Converting everything to the latter form fixed my problems.  Thanks to
everyone who responded!


	Bob Glickstein

u-tholly@wasatch.utah.edu (Troy Holly) (07/13/89)

What a wonderful place netland is, the response to my plea for help
has been fantastic.  Thanks to you all.  Here is a complete description
of the bug I encountered and it's solution.  But first a reminder of
what the problem was.

In article <2163@wasatch.utah.edu> I wrote
>CodeView debugger.  I have a line of code that passes arguments to
>the tanh() math function, but when I get there, all of the variables
>in the calling routine become undefined, and I get an "M6101 invalid"
>floating point error.  This particular line of code is executed many
>times before (it is in a loop) with no problems.  Using the debugger,
>I have traced every step of the execution, and the variables in the
>calling routine are just fine.  As soon as execution is passed to
>tanh() they become undefined; however, after examining thier memory
>locations, they are still intact.  Just before the call to the tanh()

Of course, the fist thing I checked, way before I wrote the article was
the argument.  It was indeed double, and it was of magnitude 10000 which
seemed reasonable enough.  So then I jumped into the debugger, only for
the watch window to tell me that my ALL of the arguments in the calling
procedure became undefined, which implied to me a probable stack problem.
When I looked at the addresses where these allegedly undefined variables
were, they still had the correct values.  So next I called for help, since
before the problem I was not very familiar with this segmented 
architecture stuff.  

Alright already, the problem was that arguments of magnitude 10000
are too big for the tan() function.  But I didn't think that possible
since I was using my own matherr()* function, which according to the
documentation, will be passed a structure containing error info
among other things.  Well don't you believe it!

Anyway, while in the debugger at the point where execution was passed
to tanh(), I looked at the math coprocessor registers to find my
argument sitting there with a "valid" text field next to it, so I
continued tracing (as opposed to steping) through the code; must of been 
about 100 lines of assembly code to finally find the "invalid" text
field next to a zero number in the coprocessor register.  At this
point I knew there were problems with the input arg.  So, I pull
out my HP and do a TANH on 10000 and sure enough it was out of range.
Why didn't I do that to start with!  I don't feel too bad though, since
none of you that wrote to me thought of it either.

The solution is quite simple, since tanh(x) = 1 for x > 100.

Thanks again for all of the replies.


Troy -


* (footnote)
The matherr() function is an existing Micrsoft C function that handles
errors for functions in the math library.  But if you like, you can 
supply your own version and handle the errors yourself by checking the
fields of a variable of type (struct exception *).