1
votes

My Yacc source is in pos.yacc and my Lex source is in pos1.lex, as shown.

pos1.lex

%{
#include "y.tab.h"

int yylval;
%}
DIGIT [0-9]+
%%
{DIGIT} {yylval=atoi(yytext);return DIGIT;}
[\n ] {}
. {return *yytext;}
%%

pos.yacc

%token DIGIT
%%
s:e {printf("%d\n",$1);}
e:DIGIT {$$=$1;}
|e e "+" {$$=$1+$2;}
|e e "*" {$$=$1*$2;}
|e e "-" {$$=$1-$2;}
|e e "/" {$$=$1/$2;}
;
%%
main() {
  yyparse();
}
yyerror() {
  printf("Error");
}

Compilation errors

While compiling I am getting errors like:

malathy@malathy:~$ cc lex.yy.c  y.tab.c -ly -ll
pos.y: In function ‘yyerror’:
pos.y:16: warning: incompatible implicit declaration of built-in function ‘printf’
pos.y: In function ‘yyparse’:
pos.y:4: warning: incompatible implicit declaration of built-in function ‘printf’

  • What causes those errors?
  • How am I supposed to compile Lex and Yacc source code?
3
Please use proper formatting...Tobias
... and turn off caps lock.Jon Skeet
...AND DON'T SHOUT. It's considered rude.Péter Török
... and don't tag a question "java" when it's about lex/yacc.gustafc
What did you do? People put effort into formatting your question correctly...Felix Kling

3 Answers

3
votes

printf() is defined in stdio.h so just include it above y.tab.h in pos1.lex:

%{
#include <stdio.h>
/* Add  ^^^^^^^^^^^ this line */
#include "y.tab.h"

  int yylval;
%}
DIGIT [0-9]+
%%
{DIGIT} {yylval=atoi(yytext);return DIGIT;}
[\n ] {}
. {return *yytext;}
%%
2
votes

You have the direct answer to your question from trojanfoe - you need to include <stdio.h> to declare the function printf(). This is true in any source code presented to the C compiler.

However, you should also note that the conventional suffix for Yacc source is .y (rather than .yacc), and for Lex source is .l (rather than .lex). In particular, using those sufffixes means that make will know what to do with your source, rather than having to code the compilation rules by hand.


Given files lex.l and yacc.y, make compiles them to object code using:

$ make lex.o yacc.o
rm -f lex.c 
lex  -t lex.l > lex.c
cc -O -std=c99 -Wall -Wextra -c -o lex.o lex.c
yacc  yacc.y 
mv -f y.tab.c yacc.c
cc -O -std=c99 -Wall -Wextra -c -o yacc.o yacc.c
rm lex.c yacc.c
$

This is in a directory with a makefile that sets CFLAGS = -O -std=c99 -Wall -Wextra. (This was on MacOS X 10.6.6.) You will sometimes see other similar rules used; in particular, lex generates a file lex.yy.c by default (at least on MacOS X), and you'll often see a rule such as:

lex lex.l
mv lex.yy.c lex.c
cc -O -std=c99 -Wall -Wextra -c -o lex.o lex.c

Or even:

lex lex.l
cc -O -std=c99 -Wall -Wextra -c -o lex.o lex.yy.c

The alternatives are legion; use make and it gets it right.

0
votes

Include header file stdio.h

for compilation open terminal locate both files and type

lex pos1.l

yacc pos.y

cc lex.yy.c y.tab.h -ll

./a.out

You can follow these steps.