Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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 bas.tab.c 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/cccFdeoF.o:bas.tab.c:(.text+0x0): 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 "bas.tab.h"
%}

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

[-+\n]     return *yytext;

[ \t]      ; /* skip whitespace */

.        %{
           yyerror("invalid character");

%}
%%

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading