yacc sorrows

Wade Guthrie evil at arcturus.UUCP
Wed Feb 7 11:26:04 AEST 1990


HELP!  I, an acclaimed yacc novice, am having severe difficulties
with a problem which should, by all rights, be way over my head.  
Given a yacc grammar for the C programming language (which I got 
off the net), I am trying to write an autoprototyper for ANSI C.  
Now I know what you're thinking (did he shoot six bugs or only 
five. . .): I could either buy cheaply something that does this
for me or I could be a SLIME and ask for a profiler too -- Instead,
I have opted for the most frustrating approach. . .writing my own
(I did think that it would be a good way to learn some more things
about yacc and lex).

My problem is this: I am trying to get access to the strings that
got matched by lex to make the tokens which are passed to yacc.
Given this, I can do the job (I think).  This is on a sun 3/60 under 
the 3.4 version of the operating system.  After RTFMing (and
gratuitous consultation of my local guru), I got to the part that 
says "the programmer includes in the declaration section [of the 
yacc grammar] %union { body }  This declares the yacc value stack 
[...] the value is referenced through a $$ or $n construction, yacc 
automatically inserts the appropriate union name", or some such.  
I tried this approach (and another that I will get to soon).

At this point, I would like to give an example of what I think the
pertinent pieces of code are.  The lex source looks something like:

	%{
	#include "y.tab.h"
	[...]
	%}
	[...]
	%%
	auto        { return(AUTO); }
	register    { return(REGISTER); }
	[...]
	"->"        { return(ARROW); }
	";"         { return(SEMICOLON); }
	.           { return(yytext[0]); }

And the yacc grammar that looks like . . .

	%{
	#include <stdio.h>
	[...]
	%}
	%union VALTYPE {
	    int type;
	    char *string;
	};
	%token AUTO REGISTER STATIC EXTERN TYPEDEF ENUM
	[...]
	%token COMMA SEMICOLON
	%left   COMMA
	[...]
	%left   ARROW '.'
	%%  
	translation_unit
	    : external_declaration
	    | translation_unit external_declaration
	    ;
	function_definition
	    : decln_spec declarator decln_list compound_statement
		{ printf("Found function %s\n",$2);}
	    | decln_spec declarator compound_statement
		{ printf("Found function %s\n",$2);}
	    | declarator decln_list compound_statement
		{ printf("Found function %s\n",$1);}
	    | declarator compound_statement
		{ printf("Found function %s\n",$1);}
	    ;
	[. . .]

For those that care, my y.tab.h looks something like:

	typedef union  VALTYPE {
	    int type;
	    char *string;
	} YYSTYPE;

	# define AUTO 257
	# define REGISTER 258
	[...]
	# define COMMA 318
	# define SEMICOLON 319

Which should be okay, since I compile my grammar with:

	yacc -vd grammar.y

Assuming that my interpretation of the manual is correct, this
(may I call your attention to the function_definition rule of the
yacc grammar) should give me the proper info.  Instead, the $n 
values turn out to be NULL pointers.

On another tach, I thought that I would have to (shudder) build the 
string myself, so I tried:

	type_specifier
	    : VOID
		{printf("found type %s\n",yytext);}
	[...]

in the grammar.  Now, THIS got a lot more reaction (I got core dumps).

I run the thing by having gcc remove the comments
and preprocessor directives (and piping that through a filter that
removes the '#' lines inserted by gcc) before running proto (a
simple routine that, at this point, only calls yyparse and has
a simple yyerror set up.

Anyone got any ideas?  Can normal yacc and lex do this sort of
thing?  How?  In lieu of this, can you name a good single malt
whiskey in which to drown my programming sorrows?

I appreciate any help.  Thanks.


Wade Guthrie
evil at arcturus.UUCP
Rockwell International; Anaheim, CA

(How could Rockwell stand by what I'm saying when *I* don't even know 
what I'm talking about???)



More information about the Comp.lang.c mailing list