【问题标题】:Flex and Bison GCC compile error, ld: library not found for -lflFlex 和 Bison GCC 编译错误,ld: library not found for -lfl
【发布时间】:2019-12-28 20:29:15
【问题描述】:

在为简单的扫描仪编译 flex 和 bison 源时,我遇到以下错误:

$ gcc -o lab5 lab5.tab.c lex.yy.c -lfl
ld: library not found for -lfl
clang: error: linker command failed with exit code 1 (use -v to see invocation)

lex源代码:

%{

#include <stdio.h>
#include <string.h>
#include "lab5.tab.h"
void showError();
%}

integer (\+?[1-9][0-9]*)
id ([a-zA-Z_][a-zA-Z0-9_]*)

%%

{id} {sscanf(yytext, "%s", yylval.name); return ID;}
{integer} {yylval.number = atoi(yytext); return INT;}
";" return SEMICOLON;
. {showError(); return OTHER;}

%%

void showError() {
    printf("Other input");
}

野牛源码:

%{
    #include <stdio.h>
    int yylex();
    int yyerror(char *s);
%}

%token ID INT SEMICOLON OTHER

%type <name> ID
%type <number> INT

%union {
    char name[20];
    int number;
}

%%
prog:
    stmts
;
stmts:
        | stmt SEMICOLON stmts

stmt:
        ID {
                printf("Your entered an id - %s", $1);
        }
        | INT {
                printf("The integer value you entered is - %d", $1);
        }
        | OTHER
;
%%

int yyerror(char *s) {
    printf("Syntax error on line: %s\n", s);
    return 0;
}

int main() {
    yyparse();
    return 0;
}

运行以下命令获取所有源文件:

flex -l lab5.l
bison -dv lab5.y

我正在使用 macOS Mojave 10.14.6:

  • 野牛(GNU Bison)2.3
  • flex 2.5.35 苹果(flex-31)
  • gcc 4.2.1

【问题讨论】:

    标签: c gcc bison


    【解决方案1】:

    在 OS X 上,默认的 flex 安装会安装一个名为 l 而不是 fl 的库,这使得它与原始的“lex”兼容(但与任何其他模糊的现代 flex 安装不兼容)。

    所以您可以使用-ll 代替-lfl,但不要那样做。你只需要那个库是因为你没有告诉 flex 不需要yywrap 的存在。将以下内容添加到 flex 文件的开头:

    %option noinput nounput noyywrap nodefault
    

    前两个选项通过删除它们的定义来抑制关于 inputunput 未使用的 Clang/GCC 警告。 (如果你真的使用了它们,你当然希望它们被定义。但你没有。)

    第三个选项,noyywrap,告诉 flex 在扫描器在其输入中遇到文件结束指示时抑制对yywrap 的调用。您可以添加yywrap 的定义,以无条件地确认文件结束,但这没有意义;如果您不打算使用扫描仪的该功能,那么在调用虚拟yywrap 时进行编译是没有意义的。

    第四个选项告诉 flex 如果有一些输入模式与你的规则都不匹配。默认情况下,flex 扫描器通过在标准输出(或yyout 指向的任何内容)上打印不匹配的字符来响应不匹配的输入,而不进行任何其他错误处理。这很少是你想要的,所以很高兴知道有一些输入错误会被默默地忽略,这样你就可以修复它。不幸的是,flex 没有告诉你是什么模式触发了错误,所以我会告诉你答案:. 不匹配换行符,你的 flex 文件中也没有其他任何东西。你应该解决这个问题。 (.|\n 是“其他任何东西”的模式)。

    【讨论】:

    • -ll 符合 POSIX,而 -lfl 不符合。
    • @jl2210:确实如此。大多数 flex 安装还添加了 libl 以保持 Posix 兼容性。但是本世纪的一般做法是使用-lfl。顺便说一句:C 是一种语言,而 flex 是一种扫描仪生成器。 c99 是用于运行 C 编译器的命令,lex 是用于运行扫描器生成器的命令(至少在 Posix 系统上)。我没有恢复您的编辑,但它有点刺耳;我试图在代码格式的使用上保持一致。
    • 好点。我已经删除了我所做的所有代码格式,因为它并没有真正做出太大的改进。