[comp.lang.c] Are yacc parsers portable ?

naim@eecs.nwu.edu (Naim Abdullah) (07/30/88)

[I am a sporadic reader of this newsgroup, so please forgive me if this
 question has been beaten to death here].
 
Is the C parser produced by yacc, portable ? I was looking at it and it had
stuff like:

yyparse() {

	short yys[YYMAXDEPTH];

	register short yystate, *yyps, yyn;
        ...
	yyps= &yys[-1];
	...
}

It seems to me that negative indices on arrays are probably not portable.
Is it really necessary for yacc to do these tricks, or can it produce
portable code that is just as efficient ? Is bison any better in this respect ?

Thank you.

		      Naim Abdullah
		      Dept. of EECS,
		      Northwestern University

		      Internet: naim@eecs.nwu.edu
		      Uucp: {oddjob, chinet, att}!nucsrl!naim

swilson%thetone@Sun.COM (Scott Wilson) (07/31/88)

> Is Bison any better ...

My main complaint with Bison was that both the source for Bison (last I
looked) and the parser it produces rely on alloca - a method for allocating
space on the stack that is automatically reclaimed when the function
that calls it exits.  Alloca is found on BSD derived systems and
I am told on other UNIX's.  It, however, is less than universally
available (the manual page states:  "alloca() is both machine- and
compiler-dependent; its use is discouraged").  I had a rather protected
mail war with several people associated with Bison and/or FSF regarding
this.  My opinion was that FSF would be doing computer users a greater
service by writing more portable code when possible.  The gist of the
replies I recieved was that it is "impossible" to write code that is worth
anything without taking advantage of nifty features like alloca.  I
completely disagree.

Writing portable code is not easy.  I would venture to suggest that
unportable code is much more often the result of laziness than lack
of efficiency of portable means.  Even if efficiency is of paramount
importance it is still possible to structure the code for easy porting
in the future.  As an example, in a recent piece of code I wrote I had
#ifdef vax, #ifdef sun, etc, with efficiency-minded machine-dependent
code and then for other machines I had machine-independent code.
Sure it makes the code look uglier, but it also meant the code ran
without change (albeit at less than greatest efficiency) on a Macintosh.

Scott Wilson

blandy@marduk.cs.cornell.edu (Jim Blandy) (07/31/88)

In article <3950010@eecs.nwu.edu> naim@eecs.nwu.edu (Naim Abdullah) writes:
>Is the C parser produced by yacc, portable ? I was looking at it and it had
>stuff like:
	...
>	short yys[YYMAXDEPTH];
	...
>	yyps= &yys[-1];

>It seems to me that negative indices on arrays are probably not portable.


Yacc doesn't actually dereference this pointer; it only uses it to
initialize the stack pointer for its inc-push, pop-decr stack.  yyps
will get used in a phrase like   *++yyps = uhlrich   to push uhlrich
onto the stack, and   zwingli = *yyps--   to pop zwingli off.

Portable?  ANSI says that that pointer is undefined, but I can't
imagine it ever causing any problems.  Unless there is an architecture
where one can decriment a pointer, increment it, and not get the
original value back (I'd be surprised, but not terribly surprised),
it's plenty portable, since yacc never dereferences it.

They could use a push-inc decr-pop stack, for which the equivalent
initialization would be

	yyps = yys;

which looks cleaner and <ahem> portabler.  But the advantage to using
their approach is that yyps points AT the top item, not at the top
free space; this makes it easier to look at the top of the stack
without popping, which yacc does quite often.

Since the advent of LALR, parsing is cheap enough that it doesn't take
up much of the compiler's time anyway; I'd bet this doesn't make much
of a difference...