我的Yacc源位于pos.yacc,我的Lex源位于pos1.lex,如图所示。
%{
#include "y.tab.h"
int yylval;
%}
DIGIT [0-9]+
%%
{DIGIT} {yylval=atoi(yytext);return DIGIT;}
[\n ] {}
. {return *yytext;}
%%
%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");
}
编译时遇到错误:
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’
答案 0 :(得分:3)
printf()在stdio.h中定义,所以只需将它包含在pos1.lex中的y.tab.h之上:
%{
#include <stdio.h>
/* Add ^^^^^^^^^^^ this line */
#include "y.tab.h"
int yylval;
%}
DIGIT [0-9]+
%%
{DIGIT} {yylval=atoi(yytext);return DIGIT;}
[\n ] {}
. {return *yytext;}
%%
答案 1 :(得分:2)
您可以从trojanfoe直接回答您的问题 - 您需要包含<stdio.h>
来声明函数printf()
。在提交给C编译器的任何源代码中都是如此。
但是,您还应注意Yacc来源的传统后缀为.y
(而不是.yacc
),而Lex来源为.l
(而不是.lex
)。特别是,使用这些后缀意味着make
将知道如何处理源代码,而不必手动编写编译规则。
鉴于文件lex.l
和yacc.y
,make
使用以下内容将它们编译为目标代码:
$ 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
$
这是一个包含设置CFLAGS = -O -std=c99 -Wall -Wextra
的makefile的目录。 (这是在MacOS X 10.6.6上。)您有时会看到其他类似的规则;特别是,lex
默认生成文件lex.yy.c
(至少在MacOS X上),您经常会看到如下规则:
lex lex.l
mv lex.yy.c lex.c
cc -O -std=c99 -Wall -Wextra -c -o lex.o lex.c
甚至:
lex lex.l
cc -O -std=c99 -Wall -Wextra -c -o lex.o lex.yy.c
替代品是军团;使用make
并使其正确。
答案 2 :(得分:0)
包含头文件stdio.h
用于编译 open terminal找到两个文件并输入
lex pos1.l
yacc pos.y
cc lex.yy.c y.tab.h -ll
./a.out
您可以按照以下步骤操作。