Ошибки при создании реентерабельного парсера

Я много пробовал, но не мог понять, в чем заключаются ошибки. Любое подробное объяснение этого будет очень полезно.

Итак, в основном я пытаюсь написать реентерабельный парсер, и это мои файлы.

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;}       
;

%%

Моя основная функция 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 

И мой список ошибок

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

Я просто не могу понять, что происходит не так.

Жду подробного ответа и никаких ссылок.

Я уже ссылался на эти ссылки

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

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


person Atanu    schedule 26.08.2013    source источник


Ответы (1)


Вот ряд проблем и соответствующие исправления.

  1. Сотрите прототип yylex из lex1.ll и yac1.yy. Вы не должны нигде определять это самостоятельно.

  2. Добавьте два #include в начале yac1.yy:

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

    Убедитесь, что они расположены в этом порядке, так как первый определяет YYSTYPE, который используется вторым. Это известная проблема с лексерами и парсерами flex / bison.

  3. Исправьте прототип и определение yyerror в yac1.yy. Должен быть:

    void yyerror(const char *s);
    

    Если вам нужен дополнительный параметр для ваших собственных целей из ваших собственных вызовов, вы не можете ожидать, что синтаксический анализатор предоставит его. В этом случае определите свой собственный обработчик ошибок и используйте другое имя.

После всего этого ваша программа компилируется с использованием вашего Makefile. Я не могу сказать, работает ли это так, как ожидалось.

person nickie    schedule 14.09.2013
comment
Примечание к №2: если вы используете блок %code requires в своем файле Bison, #includes нужно будет поместить в отдельный %code блок. - person cqcallaw; 30.05.2015