How to use %code provides {} to create a yyerror function from bison?


I’m trying to build a simple flex/bison scanner/parser. Following the advice of "rici" on this question – How to invoke yyerror() from flex? – I have tried putting my yyerror function in a %code provides {} block, so that it gets generated into my tab.h file. However, when I do this, I get a linker error for multiple definition of 'yyerror';

I could define my yyerror function in a header that’s included in both my .y and .l files, but the manual implies that putting it in the provides block is a reasonable tactic.

vscode ➜ /workspaces/slangy $ make
bison -t -v -d bas.y
flex bas.l
gcc -Wl,--trace-symbol=yyerror -o bas lex.yy.c
/usr/lib/gcc/aarch64-alpine-linux-musl/10.3.1/../../../../aarch64-alpine-linux-musl/bin/ld: /tmp/cccFdeoF.o: definition of yyerror
/usr/lib/gcc/aarch64-alpine-linux-musl/10.3.1/../../../../aarch64-alpine-linux-musl/bin/ld: /tmp/ccFFolkk.o: in function `yyerror':
lex.yy.c:(.text+0x0): multiple definition of `yyerror'; /tmp/ first defined here
collect2: error: ld returned 1 exit status
make: *** [Makefile:10: bas] Error 1

The parser .y file

%define parse.error detailed
%define api.pure

#include <stdio.h>

union YYSTYPE;
int yylex(union YYSTYPE *);

%code provides {
void yyerror (char const *s) {
  fprintf (stderr, "%s\n", s); 

%union {
  int ival;
  char *sval;
%token <ival> INT "integer"
%token <sval> STR "string"


expr: INT | STR;


int main() {
  return yyparse();

the scanner .l file

%option noyywrap
%option yylineno
%option bison-bridge
#include ""

[0-9]+ %{
          yylval->ival = atoi(yytext);
          return INT;

[-+\n]     return *yytext;

[ \t]      ; /* skip whitespace */

.        %{
           yyerror("invalid character");


>Solution :

In the linked answer, I said to put the declaration of yyerror() in a %code provides block. The definition of the function should be at the end, after the second %%.

In C, we never put function definitions in header files.

Leave a ReplyCancel reply