Search code examples
c++bisonflex-lexer

'yylex' was not declared in this scope, what to do?


I try to compile a g++ file within flex & bison C files, but I get the error: 'yylex' was not declared in this scope. Same case with 'yyerror'.

I've tried to put lines like these in the lexer, in the parser or in the C++ file, without success.

extern "C" {
    int yylex(void);
    int yyerror(char *s);
}

EDIT:

/* parser */
%{
#include <stdio.h>
%}

/* declare tokens */
%token NUMBER
%token ADD SUB MUL DIV ABS
%token EOL

%%

calclist: /* nothing */
 | calclist exp EOL { printf("= %d\n", $1); }
 ;

exp: factor
 | exp ADD factor { $$ = $1 + $3; }
 | exp SUB factor { $$ = $1 - $3; }
 ;

factor: term
 | factor MUL term { $$ = $1 * $3; }
 | factor DIV term { $$ = $1 / $3; }
 ;

term: NUMBER
 | ABS term   { $$ = $2 >= 0? $2 : - $2; }
;


%%

int yyerror(char *s) {
  fprintf(stderr, "error: %s\n", s);
  return 1;
}
/* lexer */
%{
    enum yytokentype {
        NUMBER = 258,
        ADD = 259,
        SUB = 260,
        MUL = 261,
        DIV = 262,
        ABS = 263,
        EOL = 264
    };
    
    int yylval;
%}

%option nounput

%%

"+"    { return ADD; }
"-"    { return SUB; }
"*"    { return MUL; }
"/"    { return DIV; }
"|"    { return ABS; }
[0-9]+ { yylval = atoi(yytext); return NUMBER; }
\n     { return EOL; }
[ \t]  { /* ignore whitespace */ }
.      { printf("Mystery character %c\n", *yytext); }

%%

C++ source code contains an "execute" function, where I call yyparse(), including the header generated by the parser, first.


Solution

  • For the file produced by bison to compile you will need to declare yylex in the bison source file:

    The easy way is just to add the following to your .y file: %{ int yylex(); %}

    But if you are using a recursive-capable parser, or have locations enabled you will need to declare that as part of the yylex prototype. And note that this gets much more complicated when you are combining multiple parsers and lexers (for example when producing a C-language compiler than combines the preprocessor and code parser into a single program because each paired parser and lexer will have different ideas about what the token types are).