Errors in making a re-entrant parser

2.4k views Asked by At

I have tried a lot, but could not figure out what the errors are. Any detailed explanation about the this will be very helpful.

So basically i am trying to write a re-entrant parser and these are my files.

Lex1.ll

%{
#include "Globals.h"
#include "yac1.tab.hh"

    extern "C"
    {
        int yylex(void);
    }


%}
alpha [A-Za-z]
digit [0-9]
%option case-insensitive
%option bison-bridge
%option reentrant
%option noyywrap
%%


"DELETE ALL" return DELALL;

"INSERT"       return INSERT;


DELETE       return DELETE;
FIND         return FIND;

(\+|\-)?[0-9]+         { return INT;    }

\n             { return ENDL; }
.    ;
%%

yac1.yy

%{
#include <stdio.h>
#include "Globals.h"
%}
%pure-parser
%error-verbose

%{

#define YYPARSE_PARAM parm
#define YYLEX_PARAM ((struct parsed_vals *)parm)->scanner
#define cast ((struct parsed_vals *) parm)

void yyerror(struct parsed_vals * parm,const char *s)
{
    fprintf(stderr, "error: %s\n", s);
}
extern "C"
{
        int yylex(void );  

      //  int yywrap()
      //  {
      //          return 1;
      //  }
}
%}

%token INSERT DELETE DELALL FIND ENDL
%union {
    int ival;
    float fval;
    char *sval;
}

%token <ival> INT
%token <fval> FLOAT
%token <sval> STRING
%%

S:T    

T:      INSERT val  {cast->cmd=INSERT_CMD;}
      | DELETE val  {cast->cmd=DELETE_CMD;}

;

val :   INT ENDL    {cast->type=INT_TYPE;
                (cast->data).int_data=$1;}   
      |
        FLOAT ENDL  {cast->type=FLOAT_TYPE;
            (cast->data).float_data=$1;}  
      |
        STRING ENDL {cast->type=STRING_TYPE;
            (cast->data).str_data=$1;}       
;

%%

My main function testlex.cc

#include <stdio.h>
#include "Globals.h"
#include "lexheader.h"
#include "yac1.tab.hh"

int yyparse(void *);
yyscan_t scanner;
main()
{

struct parsed_vals foo;
const char * buffer = "inseRt 4\n";
yylex_init(&(foo.scanner));
yyset_extra(&foo, foo.scanner);
YY_BUFFER_STATE bp = yy_scan_string( buffer, foo.scanner ); 
yy_switch_to_buffer(bp, foo.scanner);
int a; 
int ret_val = yyparse(&foo); 
yy_delete_buffer(bp, foo.scanner);  
if(ret_val!=0) printf("False");
printf ("hello %d\n",foo.data.int_data);
printf ("hello %d\n",foo.type);
yylex_destroy(foo.scanner);

}

Globals.h

/* 
 * File:   Globals.h
 * Author: atghosh
 *
 * Created on 3 August, 2013, 8:39 PM
 */

#ifndef GLOBALS_H
#define GLOBALS_H

enum CMD {INSERT_CMD=1, DELETE_CMD, FIND_CMD, DELALL_CMD};
enum TYPE {INT_TYPE=5, FLOAT_TYPE, STRING_TYPE};

struct parsed_vals{
    int cmd;
    int type;
    union{      
        int int_data;
        float float_data;
        char *str_data;
    } data;
    void * scanner;
};
#endif  /* GLOBALS_H */

Makefile

parser: lex1.ll yac1.yy testlex.cc
    bison -d yac1.yy
    flex --header-file="lexheader.h" lex1.ll
    g++ -o parser yac1.tab.cc lex.yy.c testlex.cc -lfl

clean:
    rm -rf *.o parser lexheader.h  lex.yy.c  lex.yy.cc  parser   yac1.tab.cc  yac1.tab.hh 

And my error list

bison -d yac1.yy
flex --header-file="lexheader.h" lex1.ll
g++ -o parser yac1.tab.cc lex.yy.c testlex.cc -lfl
yac1.tab.cc: In function ‘int yyparse(void*)’:
yac1.tab.cc:1302:16: error: too many arguments to function ‘int yylex()’
yac1.yy:20:13: note: declared here
yac1.tab.cc:1510:24: error: cannot convert ‘const char*’ to ‘parsed_vals*’ for argument ‘1’ to ‘void yyerror(parsed_vals*, const char*)’
yac1.tab.cc:1625:35: error: cannot convert ‘const char*’ to ‘parsed_vals*’ for argument ‘1’ to ‘void yyerror(parsed_vals*, const char*)’
In file included from testlex.cc:3:0:
lexheader.h:278:1: error: ‘YYSTYPE’ does not name a type
lexheader.h:280:18: error: variable or field ‘yyset_lval’ declared void
lexheader.h:280:18: error: ‘YYSTYPE’ was not declared in this scope
lexheader.h:280:28: error: ‘yylval_param’ was not declared in this scope
lexheader.h:280:51: error: expected primary-expression before ‘yyscanner’
lexheader.h:328:17: warning: ‘yylex’ initialized and declared ‘extern’ [enabled by default]
lexheader.h:328:17: error: ‘YYSTYPE’ was not declared in this scope
lexheader.h:328:27: error: ‘yylval_param’ was not declared in this scope
lexheader.h:328:50: error: expected primary-expression before ‘yyscanner’
lexheader.h:328:59: error: expression list treated as compound expression in initializer [-fpermissive]
make: *** [parser] Error 1

I am just not able to figure out what is going wrong.

Expecting detailed reply and no links.

I have already referred to these links

http://www.phpcompiler.org/articles/reentrantparser.html

http://plindenbaum.blogspot.in/2009/12/parsing-genetic-code-using-flex-and_14.html

1

There are 1 answers

1
nickie On

Here's a number of issues and the corresponding fixes.

  1. Erase the prototype of yylex from both lex1.ll and yac1.yy. You shouldn't have to define it yourself anywhere.

  2. Add two #include's near the beginning of yac1.yy:

    #include "yac1.tab.hh"
    #include "lexheader.h"
    

    Make sure you have them in this order, as the first one defines YYSTYPE which is used by the second one. This is a known issue with flex/bison lexers and parsers.

  3. Fix the prototype and the definition of yyerror in yac1.yy. It should be:

    void yyerror(const char *s);
    

    If you need an extra parameter there, for your own purpose from your own calls, you cannot expect the parser to provide it. In this case, define your own error handler and use a different name.

After all this, your program compiles using your Makefile. Whether it works as expected or not, I cannot tell.