[comp.unix.wizards] Yacc/Lex: multiple uses in the same program?

jwp@larry.sal.wisc.edu (Jeffrey W Percival) (09/17/89)

I am using Yacc and Lex to parse a special purpose "language", and am
in a bind.  I wrote a yacc file with my grammar, and a lex program for
finding tokens.  So far, so good.

Now, in one of my subroutines I need to pick apart a string, entirely
unrelated to the parsing that's going on.  The string has a format
consisting of a name followed by an optional offset.  The offset can be
of the form number/H for hex, number/O for octal, etc.

So I think to myself, a fledgling yacc/lex user, I can specify this as
a "mini" language, and use lex and yacc to pick it apart.  I supplied
my own input() and unput() to feed yylex from my own private string
storage.  I even remembered to put a "static" in front of the yyparse()
and yylex() definitions in my "mini" parser file, to avoid conflicts
with the "main" parser.

But when I link my main program, I run into trouble with ld(1) finding
multiple definitions of many lex variables.

How can I do what I want?
-- 
Jeff Percival (jwp@larry.sal.wisc.edu)

scjones@sdrc.UUCP (Larry Jones) (09/17/89)

In article <727@larry.sal.wisc.edu>, jwp@larry.sal.wisc.edu (Jeffrey W Percival) writes:
> [ How do I use multiple lex/yacc parsers in the same program? ]

The most common solution is to use a text editor to change all
occurrences of "yy" to "xx", "zz", or whatever you like.
----
Larry Jones                         UUCP: uunet!sdrc!scjones
SDRC                                      scjones@SDRC.UU.NET
2000 Eastman Dr.                    BIX:  ltl
Milford, OH  45150-2789             AT&T: (513) 576-2070
"I have plenty of good sense.  I just choose to ignore it."
-Calvin

djones@megatest.UUCP (Dave Jones) (09/19/89)

From article <727@larry.sal.wisc.edu>, by jwp@larry.sal.wisc.edu (Jeffrey W Percival):

> 
> But when I link my main program, I run into trouble with ld(1) finding
> multiple definitions of many lex variables.
> 
> How can I do what I want?


Several ways. (In order from probably best to probably worst...)

   1. In your makefile, use the -D option to cc to define the offending
      symbols as something else. For example,

     y.tab.o: y.tab.c y.tab.h
            cc $(CFLAGS) -Dyylval=Mpc_lval -Dyylex=Mpc_lex \
            -Dyyparse=Mpc_parse -Dyyerror=Mpc_error -c y.tab.c

   This technique can fail when the symbol in question occurs in some
   context other than that of a variable or function name, as the name of
   a structure field, for example. But in the case of a "pure" y.tab.c file
   with nothing strange going on in the semantic actions, no harm.

   This is generally a little safer than number 2:

   2. Run an awk or sed script over the y.tab.c file, changing the
      names mechanically. That also should go into the makefile.
      You generally don't want to do such things, because the string
      you are replacing can occur in other contexts, literal strings,
      for example. But in this case, generally no harm.

Number 3 would be the "right" way if there were a standard, powerful
object-file editor universally available: Edit the symbol-table in
the object file. But alas, "ld" is not up to the task. (And even if
it were, it is not universally available on all systems that have
yacc.) So number 3 is probably right out.

jwp@larry.sal.wisc.edu (Jeffrey W Percival) (09/19/89)

In article <8106@goofy.megatest.UUCP> djones@megatest.UUCP (Dave Jones) writes:
>From article <727@larry.sal.wisc.edu>, by jwp@larry.sal.wisc.edu (Jeffrey W Percival):
>> But when I link my main program, I run into trouble with ld(1) finding
>> multiple definitions of many lex variables.
>> How can I do what I want?
>Several ways. (In order from probably best to probably worst...)

Thanks for the info...  I'm almost sorry I asked.


Some people recommended using Flex and Bison, which are claimed to
avoid this pathetic and debilitating flaw in a couple of otherwise
*great* programs.
-- 
Jeff Percival (jwp@larry.sal.wisc.edu)

khera@juliet.cs.duke.edu (Vick Khera) (09/19/89)

In article <8106@goofy.megatest.UUCP> djones@megatest.UUCP (Dave Jones) writes:
>From article <727@larry.sal.wisc.edu>, by jwp@larry.sal.wisc.edu (Jeffrey W Percival):
>> But when I link my main program, I run into trouble with ld(1) finding
>> multiple definitions of many lex variables.
>> How can I do what I want?
>Several ways. (In order from probably best to probably worst...)
>   1. In your makefile, use the -D option to cc to define the offending
>      symbols as something else. For example,
>   2. Run an awk or sed script over the y.tab.c file, changing the
>      names mechanically. That also should go into the makefile.
>Number 3 would be the "right" way if there were a standard, powerful
>object-file editor universally available: Edit the symbol-table in
>the object file. 

another alternative is to use a newer program. flex is a faster lex that
also happens to produce scanners that declare all variables as static.  it
also has quite a few options that are quite useful.  there are a few minor
differences between flex and lex, but they are easily overcome.

as for yacc, the GNU project has a version called bison. it generates
parsers with mostly static declarations. i am not sure if the ones that are
not static need to be that way.  there is also a newly released parser
generator that is having an identity crisis: is it called "zoo" still?  i
have no experience with this one, though.

							vick.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
ARPA:	khera@cs.duke.edu		Department of Computer Science
CSNET:	khera@duke			Duke University
UUCP:	{mcnc,decvax}!duke!khera	Durham, NC 27706