0

I'm trying to create a compiler in flex and bison, but unfortunately I'm finding some problem.

When I try to compile the compiler gives me these types of error:

flex.lex.c:286:37: error: expected ‘)’ before ‘->’ token
 #define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
flex.lex.c:139:19: note: in expansion of macro ‘YY_CURRENT_BUFFER_LVALUE’ #define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
dichiarazioni.h:2:12: note: in expansion of macro ‘yylineno’
extern int yylineno; /* from lexer */
flex.lex.c:134:17: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘->’ token #define yyin yyg->yyin_r
dichiarazioni.h:5:14: note: in expansion of macro ‘yyin’
 extern FILE *yyin;
make: *** [<incorporato>: flex.lex.o] Error 1

Then I show you three part of file of my program (flex.l bison.y and dichiarazioni.h).

flex.l:

  %option header-file="flex.lex.h"
  %option reentrant bison-bridge
  %{
    #include "bison.tab.h"
    #include "dichiarazioni.h"
  %}

   %%

    "char"  { yylval->fn = 10; return TYPE; }
    "int"   { yylval->fn = 11; return TYPE; }
    "if"|"IF"               { return IF; }
    "else"|"ELSE"           { return ELSE; }

    "inc"                   { yylval->fn = 24; return OPERATORE; }
    "dec"                   { yylval->fn = 25; return OPERATORE; }
    "set"                   { yylval->fn = 26; return OPERATORE; } 

     etc etc
     %%

bison.y:

 %{
 #include <stdio.h>
 #include <stdlib.h>
 %}

 %{
 #include "flex.lex.h"
 #include "dichiarazioni.h"
 %}

 %define api.value.type {union YYSTYPE}

%token NUMBER
%token <fn> TYPE
%token SEMI
%token ALPHA
%token ELIF
%token <fn> CMP
%token <fn> OPERATORE
%token <fn> PRINT
.......

%type <fn> term NUMBER
%type <op> operazioni
%type <c> ALPHA string
.....
%start main

%%

string: ALPHA 
;
.....
%%

dichiarazioni.h:

extern int yylineno; /* from lexer */
void yyerror(char *s, ...);
extern int yyparse();
extern FILE *yyin;
//extern int yylex();

union YYSTYPE{
    int fn;
    char* c;
    struct operazioni* op;
    ....
 };
user207421
  • 305,947
  • 44
  • 307
  • 483
  • 2
    Please try to ensure that your included code is correctly indented. As shown, it cannot work because flex requires that patterns (and some other lines) appear exactly at the beginning of the line. Pasting incorrect code is confusing because it makes it impossible to test the code. – rici Dec 05 '19 at 18:09
  • 2
    Also, it is always best to include a [mre], which is a complete self-contained program. Instead of replacing large segments of your code with `etc etc` or similar comments, reduce the size of your program by building a simplified but compilable subset of the functionality. Particularly when you're starting out with flex and bison, you'll find it easier to experiment with a minimal skeleton before adding all the rest of the functionality you need. – rici Dec 05 '19 at 18:10

2 Answers2

1

If you want to use a reentrant lexer, you need to carefully read the sections of the manual which describe the changes to the API. In particular, neither yyin nor yylineno are global variables, and the prototype for yylex is not yylex(void). Moreover, flex uses preprocessor macros so that in a reentrant lexer, you can still refer to yyin and other standard variables as though they were globals. But outside of flex actions, you must use the reentrant accessor and setter functions with the scanner context object.

You also will need to create and initialize the scanner object somewhere in your program, and pass it into the parser as an extra argument. It's a bit tricky to accomplish this without creating a circular header dependency; you can take a look at this answer for a detailed suggested approach for working around this problem. (But read the manual first :-) )

Also, I'd recommend letting bison generate the union declaration for YYSTYPE instead of doing it yourself in your own header file, by using a %union declaration in your grammar file. But perhaps I'm just being old-fashioned. :-)

rici
  • 234,347
  • 28
  • 237
  • 341
0

You're using %option bison-bridge without using %pure-parser in the bison parser, which won't work -- bison-bridge is for connecting with the (non standard) reentrant API used by bison's %pure-parser option.

Either get rid of %option bison-bridge from the .l file or add %pure-parser to the .y file. If you do the latter, you'll also need to change your .h file as well (yyerror/yyparse change, yyin and yylineno go away).

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226