Bart Vandewoestyne <
MyFirstName...@telenet.be> writes:
> I am currently trying to get started with the code for Chapter 3
> 'Parsing' in Appel's 'Modern Compiler Implementation in C'. After
> downloading the files and fixing some small bugs in it, the only problem
> I'm left with when typing 'make' is the following error:
>
> cc -g -c lex.yy.c
> lex.yy.c:20:1: error: initializer element is not constant
> lex.yy.c:20:1: error: (near initialization for �yyin�)
> lex.yy.c:20:1: error: initializer element is not constant
> lex.yy.c:20:1: error: (near initialization for �yyout�)
> make: *** [lex.yy.o] Error 1
>
> The file lex.yy.c is an output file of an old version of lex, and the
> error is for the line:
>
> FILE *yyin = {stdin}, *yyout = {stdout};
Apparently lex is assuming that stdin and stdout are constant
expressions. This is likely true for some implementations,
presumably including the ones on which lex was originally developed,
but it's not guaranteed.
> I would now like to know what is the cleanest way to solve this
> compilation error. From the net, I've found that I can simply declare
> yyin and yyout:
>
> FILE *yyin, *yyout;
>
> (which works), and then later initialize them in a main(), probably
> something like:
>
> int main()
> {
> yyin = stdin;
> yyout = stdout;
> }
>
> However, i don't have a main function, so I was wondering where and how
> I should initialize yyin and yyout.
You should have a main function *somewhere*.
> My educated guess is that this
> should happen at the beginning of the yylex() function. So there, I added:
>
> yylex() {
> int nstr; extern int yyprevious;
> yyin = stdin; yyout = stdout;
> ... other code...
Can you create an initialization function that assigns values to yyin
and yyout, and require that the main program (wherever it is) must call
that function?
That file no longer exists. The version I think you're referring to can
be seen at
https://github.com/BartVandewoestyne/c/blob/cb0daed9ee4b0bd8c803980c89095ae84f36f706/books/Modern_Compiler_Implementation_in_C/chap03/lex.yy.c
The file lex.yy.c is normally *generated* from an input file. Your
makefile assumes that it already exists.
GNU flex is a relatively newer implementation of lex, and it should be
reasonable compatible. I just tried feeding your "tiger.lex" file to
yacc, and it generated a lex.yy.c file that doesn't have the problem you
reported. It has:
if ( ! yyin )
yyin = stdin;
if ( ! yyout )
yyout = stdout;
--
Keith Thompson (The_Other_Keith)
ks...@mib.org <
http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"