Path: utzoo!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!samsung!usc!elroy.jpl.nasa.gov!zardoz.cpd.com!dhw68k!arcturus!evil From: evil@arcturus.UUCP (Wade Guthrie) Newsgroups: comp.lang.c Subject: yacc sorrows Message-ID: <7179@arcturus> Date: 7 Feb 90 00:26:04 GMT Organization: Rockwell International, Anaheim, CA Lines: 123 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 [...] %} %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@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???)