Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!cs.utexas.edu!uunet!mcsun!ukc!reading!chive!ac1 From: ac1@chive.cs.reading.ac.uk (Andrew Cunningham) Newsgroups: comp.unix.wizards Subject: Re: yacc & lex - cupla questions Keywords: yacc lex compiler parse Message-ID: <2481@onion.reading.ac.uk> Date: 28 Jul 90 21:44:53 GMT References: <1990Jul26.175831.1216@uicbert.eecs.uic.edu> Sender: news@reading.ac.uk Reply-To: ac1@rosemary.cs.reading.ac.uk (Andrew Cunningham) Distribution: comp Organization: Comp. Sci. Dept., Reading Univ., UK. Lines: 83 In article <1990Jul26.175831.1216@uicbert.eecs.uic.edu> woodward@uicbert.eecs.uic.edu writes: > >i have been trying to parse a straightforward stream of bytes using the >c-preprocessors lex & yacc. being a new user of these utilities, i have >a couple of problems for which i'd like to solicit your suggestions: > >--------------------------------------------------------------------- >1.) how does one redefine the i/o in a yacc/lex piece of code? i.e. >the code which is generated defaults to stdin and stdout for input and >output, respectively. i'd like to redefine these defaults w/o having >to hack on the intermediate c-code, since this is a live production >project; i'd like to be able to update and modify the program simply by >saying "make". There are two approaches to this. You can either close stdin and reopen it to point to your input file or #define yyinput to be something which returns the character from your file. Then, when lex.yy.c is compiled, instead of calling the yyinput function your #define is called instead. E.g. #define yyinput my_yyinput int my_yyinput() { /* get the character you want and return it */ } You'll also have to redefine yyunput(c) if you want to do this. >--------------------------------------------------------------------- >2.) how can one get the automagically-defined #defines, which can >normally be created from yacc with the -d flag, to come out when you >use a makefile? i.e. suppose i have lex.l and yacc.y lex and yacc >source files, respectively, and i have object files defined in my makefile >called lex.o and yacc.o such that "make" follows default rules to create >these from the aforementioned source files. You'll need to specify an explicit rule to do this. Or, at the expense of some processor time you might want to run: y.tab.h: yacc.y yacc yacc.y rm y.tab.c (This shouldn't take too long, yacc is *fast* compared with the cc stage) >--------------------------------------------------------------------- >3.) if i have a yacc construct such as: > >line3 : A B C > { yacc action sequence } > > >which indicates that the construct line3 is composed of the 3 tokens >A B and C, in that order ... > >how can i now assign the values of A, B, and C into local vars of my >choice? the problem lies in the fact that each of A B and C represent >three calls to lex, and if i pass back a pointer to yytext[] from lex, >i only retain the value of the last token in the sequence, in this case C, >when i get to the action sequence in my yacc code. what if i want to >be able to select the EXACT ascii tokens for each of A B and C above in >my yacc code. how do i do that? line3: A {atext=strdup(yytext);} B {btext=strdup(yytext);} C {ctext=strdup(yytxet);} Note: if you're grammar is more comlex than this you can lead to all sorts of comflicts in the compiler - when the parser executes an action it is `committed' to that branch of the parse tree and cannot backtrack to resolve any ambiguity that might occur (the classic problem here is if ... then ... else in programming languages). Hope this information helps. AndyC Yours etc, | e-mail: ac1@csug.cs.reading.ac.uk Captain B.J. Smethwick |------------------------------------------ in a white wine sauce with | Nobody agrees with my opinions, though shallots, mushrooms and garlic. | everybody is entitled to them.