Thread View: comp.unix.programmer
3 messages
3 total messages
Started by Chris Curtin
Fri, 05 Oct 1990 12:50
yacc/bison question
Author: Chris Curtin
Date: Fri, 05 Oct 1990 12:50
Date: Fri, 05 Oct 1990 12:50
16 lines
947 bytes
947 bytes
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
Re: yacc/bison question
Author: Michael Meissner
Date: Sun, 07 Oct 1990 01:11
Date: Sun, 07 Oct 1990 01:11
130 lines
5742 bytes
5742 bytes
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?
Re: yacc/bison question
Author: Dan Salomon
Date: Fri, 12 Oct 1990 21:40
Date: Fri, 12 Oct 1990 21:40
20 lines
1257 bytes
1257 bytes
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
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads