从lex和yacc语法生成编译器

从lex和yacc语法生成编译器,c,yacc,lex,C,Yacc,Lex,我正在尝试生成一个编译器,这样我可以在编译后向他传递一个.c文件 我从下载了YACC和LEX语法,并将它们命名为clexyacc.l和clexyacc.y 在终端上生成时,我执行了以下操作: yacc -d clexyacc.y lex clexyacc.l 一切顺利。 当我转到最后一部分时,我发现了一些错误 最后一部分是:cc lex.yy.c y.tab.c-oclexyacc.exe 但我有以下错误: 您使用的yacc版本正在生成对C99无效的C代码 它生成的代码在调用函数yylex或y

我正在尝试生成一个编译器,这样我可以在编译后向他传递一个.c文件

我从下载了YACC和LEX语法,并将它们命名为clexyacc.l和clexyacc.y

在终端上生成时,我执行了以下操作:

yacc -d clexyacc.y
lex clexyacc.l
一切顺利。 当我转到最后一部分时,我发现了一些错误

最后一部分是:cc lex.yy.c y.tab.c-oclexyacc.exe

但我有以下错误:


您使用的yacc版本正在生成对C99无效的C代码

它生成的代码在调用函数yylex或yyerror之前不包含它们的声明。这就产生了警告。在yyerror的情况下,它还导致隐式声明与后面的实际定义不匹配

您可以通过在.y文件顶部包含以下内容来解决此问题:

%{
int yylex();
void yyerror(const char *s);
%}
或者,您可以切换到更现代的yacc编译器


另请参见:

如何在lexer文件中定义
yyerror
?请参阅:在我的clex.l文件中,我只有两个对yyerror的引用,它们是:extern void yyerror(const char*);yyerror(“未终止的评论”);我应该将它们添加到yacc文件的顶部,对吗?我已经在yacc文件的顶部添加了“%{int yylex();void yyerror(const char*s);%}”。编译最后一部分时,我现在得到:“架构x86_64的未定义符号:”\u main“,引用自:主可执行文件的隐式条目/开始ld:symbol未找到架构x86_64 clang:error:linker命令失败,退出代码为1(使用-v查看调用)”,您正在尝试将其编译为可执行文件,在你的程序中没有主函数。解析器/词法分析器本身不做任何事情,您需要编写一个主函数来传递一个文件,并对解析结果进行处理。或者只是将它编译成一个对象文件,而不链接,然后链接到一个包含main的对象(后面是-c选项)。所以你是说我应该坚持使用“yacc-d clexyacc.y lex clexyacc.l”部分,然后把它编译成一个.c文件?我仍然会把它编译成一个.o文件,否则你不知道它是否包含有效的语法。使用:
cc-c lex.yy.cy.tab.c
。c选项告诉它生成.o(对象)文件,您可以稍后将其链接到.c文件
%{
int yylex();
void yyerror(const char *s);
%}