Flex 和 Bison GCC 编译错误,ld:找不到 -lfl 的库

Ale*_*rie 1 c gcc bison

在为简单扫描仪编译 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)
Run Code Online (Sandbox Code Playgroud)

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");
}
Run Code Online (Sandbox Code Playgroud)

野牛源代码:

%{
    #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;
}
Run Code Online (Sandbox Code Playgroud)

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

flex -l lab5.l
bison -dv lab5.y
Run Code Online (Sandbox Code Playgroud)

我正在使用 macOS Mojave 10.14.6 和:

  • 野牛 (GNU Bison) 2.3
  • flex 2.5.35 苹果(flex-31)
  • 海湾合作委员会 4.2.1

ric*_*ici 5

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

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

%option noinput nounput noyywrap nodefault
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • @jl2210:确实如此。大多数 Flex 安装还添加“libl”以保持 Posix 兼容性。但本世纪的一般做法是使用“-lfl”。顺便说一句:C 是一种语言,flex 是一个扫描仪生成器。`c99` 是用于运行 C 编译器的命令,而 `lex` 是用于运行扫描器生成器的命令(至少在 Posix 系统上)。我没有恢复你的编辑,但这有点令人烦恼;我试图在代码格式的使用上保持一致。 (3认同)