4
votes

When I run make all on the following Makefile I get this error:

Makefile:5: *** missing separator. Stop.

What's wrong with it and how do I fix it?

LEX = lex
YACC = yacc 
CC = gcc
calcu: y.tab.o lex.yy.o
$(CC) -o calcu y.tab.o lex.yy.o -ly -lfl
y.tab.c y.tab.h: parser.y
$(YACC) -d parser.y
y.tab.o: y.tab.c parser.h
$(CC) -c y.tab.c
lex.yy.o: y.tab.h lex.yy.c 
$(CC) -c lex.yy.c
lex.yy.c: calclexer.l parser.h
$(LEX) calclexer.l
clean:
rm *.o
rm *.c
rm calcu
4

4 Answers

11
votes

G'day,

You need tabs to indent the lines underneath each target.

LEX = lex
YACC = yacc 
CC = gcc
calcu: y.tab.o lex.yy.o
    $(CC) -o calcu y.tab.o lex.yy.o -ly -lfl
y.tab.c y.tab.h: parser.y
    $(YACC) -d parser.y
y.tab.o: y.tab.c parser.h
    $(CC) -c y.tab.c
lex.yy.o: y.tab.h lex.yy.c 
    $(CC) -c lex.yy.c
lex.yy.c: calclexer.l parser.h
    $(LEX) calclexer.l
clean:
    rm *.o
    rm *.c
    rm calcu

BTW General convention is that you should use braces rather than brackets for your macros. Using brackets are a legacy thing left over from substituting an object back in to an archive. So the above is better expressed as:

LEX = lex
YACC = yacc 
CC = gcc
calcu: y.tab.o lex.yy.o
    ${CC} -o calcu y.tab.o lex.yy.o -ly -lfl
y.tab.c y.tab.h: parser.y
    ${YACC} -d parser.y
y.tab.o: y.tab.c parser.h
    ${CC} -c y.tab.c
lex.yy.o: y.tab.h lex.yy.c 
    ${CC} -c lex.yy.c
lex.yy.c: calclexer.l parser.h
    ${LEX} calclexer.l
clean:
    rm *.o
    rm *.c
    rm calcu

HTH

7
votes

You need to indent like so. (Note: they changed my tabs into a 4space. Make sure to indent with the tab character.)

LEX = lex
YACC = yacc 
CC = gcc

calcu: y.tab.o lex.yy.o
    $(CC) -o calcu y.tab.o lex.yy.o -ly -lfl

y.tab.c y.tab.h: parser.y
    $(YACC) -d parser.y

y.tab.o: y.tab.c parser.h
    $(CC) -c y.tab.c

lex.yy.o: y.tab.h lex.yy.c 
    $(CC) -c lex.yy.c

lex.yy.c: calclexer.l parser.h
    $(LEX) calclexer.l

clean:
    rm *.o
    rm *.c
    rm calcu

The extra blank lines aren't required but the indenting is. You'll also need to make an all rule if you want to make all.

5
votes

Generally, this sort of error means that you have erroneously used spaces instead of a tab when indenting lines in your Makefile.

Your example appears to have been pasted without indenting, but I can't tell whether your file really looks like that or whether there was a paste error. In the following:

calcu: y.tab.o lex.yy.o
        $(CC) -o calcu y.tab.o lex.yy.o -ly -lfl

the whitespace before $(CC) must be a tab, not spaces:

calcu: y.tab.o lex.yy.o
        $(CC) -o calcu y.tab.o lex.yy.o -ly -lfl
|tab-->|
2
votes

Whitespace formatting can make answering this difficult. In Make whitespace is critical. Actions must have a tab character in front to be recognised as such by Make. e.g.


calcu: y.tab.o lex.yy.o
\t$(CC) -o calcu y.tab.o lex.yy.o -ly -lfl y.tab.c y.tab.h: parser.y

Note that \t means <tab>. Not 4 spaces, not any spaces, but tab!

Also ensure there is a blank line between dependencies, i.e. if you're going to say file: dependencies then ensure there is a blank line immediately above.