chris@bwilab3.UUCP (Chris Curtin) (10/05/90)
I am looking for a way to have multiple yacc/bison routines in a program. I also need to be able to name them anything, not just yyparse1 etc. I know that doing a global replace with the preprocessor will not work because of the use of globals in calls to library routines. If this is possible it will make my life much easier and produce better quality code. (Now I have to hand parse all input and it gets tedious and error prone). Thanks in advance. Chris Curtin ...!gatech!galbp!bwilab3!chris
meissner@osf.org (Michael Meissner) (10/07/90)
In article <122@bwilab3.UUCP> chris@bwilab3.UUCP (Chris Curtin) writes: | I am looking for a way to have multiple yacc/bison routines in a program. I | also need to be able to name them anything, not just yyparse1 etc. | | I know that doing a global replace with the preprocessor will not work because | of the use of globals in calls to library routines. | | If this is possible it will make my life much easier and produce better quality | code. (Now I have to hand parse all input and it gets tedious and error prone). This seems to come up regularly on comp.compilers and comp.lang.misc, which might have been better groups to ask. In any case, bison has extensions to handle this with no problem -- RTFM. The traditional ways to do it with yacc are to go through and change the names with either sed or the preprocessor. With sed, you just change all 'yy' and 'YY' to some other prefix. With the preprocessor, you use #defines, and you can get burned if your vendor changes the yacc skeleton file and some new name is added. The relavant sections from the bison manual are quoated below (to get a different named file, just use the -o <file> option, and -d and -v will adjust themselves accordingly): File: bison.info Node: Multiple Parsers, Prev: Declarations, Up: Grammar File Multiple Parsers in the Same Program ==================================== Most programs that use Bison parse only one language and therefore contain only one Bison parser. But what if you want to parse more than one language with the same program? Here is what you must do: * Make each parser a pure parser (*Note Pure Decl::). This gets rid of global variables such as `yylval' which would otherwise conflict between the various parsers, but it requires an alternate calling convention for `yylex' (*Note Pure Calling::). * In each grammar file, define `yyparse' as a macro, expanding into the name you want for that parser. Put this definition in the C declarations section (*Note C Declarations::). For example: %{ #define yyparse parse_algol %} Then use the expanded name `parse_algol' in other source files to call this parser. * If you want different lexical analyzers for each grammar, you can define `yylex' as a macro, just like `yyparse'. Use the expanded name when you define `yylex' in another source file. If you define `yylex' in the grammar file itself, simply make it static, like this: %{ static int yylex (); %} %% ... GRAMMAR RULES ... %% static int yylex (yylvalp, yyllocp) YYSTYPE *yylvalp; YYLTYPE *yyllocp; { ... } * If you want a different `yyerror' function for each grammar, you can use the same methods that work for `yylex'. File: bison.info Node: Pure Decl, Prev: Start Decl, Up: Declarations, Next: Decl Summary Requesting a Pure (Reentrant) Parser ------------------------------------ A "reentrant" program is one which does not alter in the course of execution; in other words, it consists entirely of "pure" (read-only) code. Reentrancy is important whenever asynchronous execution is possible; for example, a nonreentrant program may not be safe to call from a signal handler. In systems with multiple threads of control, a nonreentrant program must be called only within interlocks. The Bison parser is not normally a reentrant program, because it uses statically allocated variables for communication with `yylex'. These variables include `yylval' and `yylloc'. The Bison declaration `%pure_parser' says that you want the parser to be reentrant. It looks like this: %pure_parser The effect is that the the two communication variables become local variables in `yyparse', and a different calling convention is used for the lexical analyzer function `yylex'. *Note Pure Calling::, for the details of this. The variable `yynerrs' also becomes local in `yyparse' (*Note Error Reporting::). The convention for calling `yyparse' itself is unchanged. File: bison.info Node: Pure Calling, Prev: Token Positions, Up: Lexical Calling Convention for Pure Parsers ----------------------------------- When you use the Bison declaration `%pure_parser' to request a pure, reentrant parser, the global communication variables `yylval' and `yylloc' cannot be used. (*Note Pure Decl::.) In such parsers the two global variables are replaced by pointers passed as arguments to `yylex'. You must declare them as shown here, and pass the information back by storing it through those pointers. yylex (lvalp, llocp) YYSTYPE *lvalp; YYLTYPE *llocp; { ... *lvalp = value; /* Put value onto Bison stack. */ return INT; /* Return the type of the token. */ ... } -- Michael Meissner email: meissner@osf.org phone: 617-621-8861 Open Software Foundation, 11 Cambridge Center, Cambridge, MA, 02142 Do apple growers tell their kids money doesn't grow on bushes?
salomon@ccu.umanitoba.ca (Dan Salomon) (10/13/90)
In article <122@bwilab3.UUCP> chris@bwilab3.UUCP (Chris Curtin) writes: > > >I am looking for a way to have multiple yacc/bison routines in a program. I >also need to be able to name them anything, not just yyparse1 etc. > I once needed two lex-yacc parsers in the same program. I used the stream editor "sed" to edit the C code generated by lex & yacc on one of the parsers. It replaced every occurence of "yy" with "ww". This worked because all lex-yacc externals start with "yy". I also supplied the needed external procedures such as "wwerror". My sed script also renamed the main parser routine, but kept the same number of letters, just to be safe. This approach worked fine, but it was just quick & dirty code for an experiment; it wasn't production quality code. -- Dan Salomon -- salomon@ccu.UManitoba.CA