1
votes

While compiling the flex and bison sources for a simple scanner I encounter the following error:

$ 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)

The lex source code:

%{

#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");
}

The bison source code:

%{
    #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 the following commands to have all the source files:

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

I am using macOS Mojave 10.14.6 with:

  • bison (GNU Bison) 2.3
  • flex 2.5.35 Apple(flex-31)
  • gcc 4.2.1
1

1 Answers

5
votes

On OS X, the default flex installation installs a library called l instead of fl, which makes it compatible with the original "lex" (but incompatible with any other vaguely modern installation of flex).

So you could use -ll instead of -lfl but don't do that. You only need that library because you haven't told flex not to require the presence of yywrap. Add the following to the very beginning of your flex file:

%option noinput nounput noyywrap nodefault

The first two of those options suppress a Clang/GCC warning about input and unput not being used, by removing their definitions. (If you actually used them, you would want them to be defined, of course. But you don't.)

The third option, noyywrap, tells flex to suppress the call to yywrap when the scanner encounters an end-of-file indication on its input. You could add a definition of yywrap that unconditionally confirms the end-of-file, but that's pointless; if you aren't going to use that feature of the scanner, there's no point compiling in a call to a dummy yywrap.

The fourth option tells flex to complain if there is some input pattern which none of your rules match. By default, a flex scanner responds to unmatchable input by printing the unmatchable character on standard output (or whatever yyout is pointing at) without any other error handling. That's very rarely what you want, so it's good to know that there is some input error which will be silently ignored, so that you can fix it. Unfortunately, flex doesn't tell you what pattern triggers the error, so I'll let you in on the answer: . doesn't match a newline character, and nothing else in your flex file does either. You should fix that. (.|\n is the pattern for "anything else").