phil@RICE.ARPA (William LeFebvre) (03/29/85)
About a week ago, I sent out a message outlining some problems I had getting pic (the simple graphics preprocessor for ditroff) working on a SUN workstation. I've determined exactly what the problem is and I've come up with a reasonable work-around. My original solution was pretty sleazy and depended on Reiser preprocessor behavior. The one I give here has NO such dependencies. Thanks to Tim Morgan at uci-icsa for providing the idea for this solution. The basic problem is that all the tokens and productions in the yacc grammar are typed. So, none of them have the type that YYSTYPE does (which is a union). Rather, they each have the type of a specific member of the union. For more information on how yacc handles typed productions, I suggest you read the yacc paper. Two routines, "makeattr" and "makevar" were expecting a YYSTYPE union as their last argument. This makes sense since these build nodes that contain arbitrary values. However, they were passed a production's value which (as I said earlier) is a specific member of the union. It turns out that this worked okay for all the members of the union except one -- the float. The caller saw a float, so it was passed on the stack as a double. The callee was expecting a 4 byte union. You should be able to figure out the rest. Naturally, because of byte order, this worked on a VAX but not on a Sun. The solution is to pass a YYSTYPE instead of a specific member. So, I added some macros to the beginning of the yacc grammar to make this easier. Along the way, I noticed a similar problem with the troffgen function and the corresponding TROFF token. This was easier to change, since the only reasonable thing to pass to troffgen is a string. This may seem confusing at first, but if you spend some time looking at picy.y, troffgen.c, and misc.c and the diffs, things should become a little clearer. William LeFebvre Department of Computer Science Rice University <phil@Rice.arpa> There are two diffs here: one for picy.y and the other for troffgen.c. These diffs were made against the original source (I hope). The file "on the left" is the original. -------------------- picy.y: 4a5,13 > > /* macros for proper interface to makeattr and makevar routines */ > #define makeattrf(a, b) (y.f = b, makeattr(a, y)) > #define makeattri(a, b) (y.i = b, makeattr(a, y)) > #define makeattro(a, b) (y.o = b, makeattr(a, y)) > #define makeattrp(a, b) (y.p = b, makeattr(a, y)) > > #define makevarf(a, b, c) (y.f = c, makevar(a, b, y)) > #define makevaro(a, b, c) (y.o = c, makevar(a, b, y)) 15c24 < %token <i> TROFF 9 --- > %token <p> TROFF 9 59,62c68,71 < | PLACENAME ':' picture { makevar($1, PLACENAME, $3); $$ = $3; } < | PLACENAME ':' ST picture { makevar($1, PLACENAME, $4); $$ = $4; } < | PLACENAME ':' position ST { makevar($1, PLACENAME, $3); $$ = $3; } < | VARNAME '=' expr ST { makevar($1, VARNAME, $3); checkscale($1); } --- > | PLACENAME ':' picture { makevaro($1, PLACENAME, $3); $$ = $3; } > | PLACENAME ':' ST picture { makevaro($1, PLACENAME, $4); $$ = $4; } > | PLACENAME ':' position ST { makevaro($1, PLACENAME, $3); $$ = $3; } > | VARNAME '=' expr ST { makevarf($1, VARNAME, $3); checkscale($1); } 98,107c107,116 < ATTR opt_expr { makeattr($1, $2); } < | DIR opt_expr { makeattr($1, $2); } < | FROM position { makeattr($1, $2); } < | TO position { makeattr($1, $2); } < | AT position { makeattr($1, $2); } < | BY position { makeattr($1, $2); } < | WITH CORNER { makeattr(WITH, $2); } < | WITH '.' PLACENAME { makeattr(PLACE, getblock(getlast(1,BLOCK), $3)); } < | WITH position { makeattr(PLACE, $2); } < | SAME { makeattr(SAME, $1); } --- > ATTR opt_expr { makeattrf($1, $2); } > | DIR opt_expr { makeattrf($1, $2); } > | FROM position { makeattro($1, $2); } > | TO position { makeattro($1, $2); } > | AT position { makeattro($1, $2); } > | BY position { makeattro($1, $2); } > | WITH CORNER { makeattri(WITH, $2); } > | WITH '.' PLACENAME { makeattro(PLACE, getblock(getlast(1,BLOCK), $3)); } > | WITH position { makeattro(PLACE, $2); } > | SAME { makeattri(SAME, $1); } 109,112c118,121 < | HEAD { makeattr(HEAD, $1); } < | DOT opt_expr { makeattr(DOT, $2); } < | DASH opt_expr { makeattr(DASH, $2); } < | CHOP opt_expr { makeattr(CHOP, $2); } --- > | HEAD { makeattri(HEAD, $1); } > | DOT opt_expr { makeattrf(DOT, $2); } > | DASH opt_expr { makeattrf(DASH, $2); } > | CHOP opt_expr { makeattrf(CHOP, $2); } 122,125c131,134 < TEXT { makeattr(CENTER, $1); } < | TEXT textattr { makeattr($2, $1); } < | textlist TEXT { makeattr(CENTER, $2); } < | textlist TEXT textattr { makeattr($3, $2); } --- > TEXT { makeattri(CENTER, $1); } > | TEXT textattr { makeattri($2, $1); } > | textlist TEXT { makeattri(CENTER, $2); } > | textlist TEXT textattr { makeattri($3, $2); } -------------------- troffgen.c: 6c6 < YYSTYPE s; --- > char *s; 10c10 < if (strncmp(s.p, ".PS", 3) == 0) --- > if (strncmp(s, ".PS", 3) == 0) 12c12 < savetext(CENTER, s.p); /* use the existing text mechanism */ --- > savetext(CENTER, s); /* use the existing text mechanism */