我已经尝试了很多,但无法弄清楚错误是什么。 任何关于此的详细解释都将非常有用。
所以基本上我正在尝试编写一个可重入的解析器,这些是我的文件。
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 */
生成文件
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://www.phpcompiler.org/articles/reentrantparser.html
http://plindenbaum.blogspot.in/2009/12/parsing-genetic-code-using-flex-and_14.html
答案 0 :(得分:2)
以下是一些问题和相应的修复方法。
从yylex
和lex1.ll
中删除yac1.yy
的原型。你不应该在任何地方自己定义它。
在#include
的开头附近添加两个yac1.yy
:
#include "yac1.tab.hh"
#include "lexheader.h"
确保按此顺序 ,因为第一个定义了YYSTYPE
,第二个使用了yyerror
。这是flex / bison词法分析器和解析器的已知问题。
在yac1.yy
中修复原型和void yyerror(const char *s);
的定义。它应该是:
Makefile
如果你需要一个额外的参数,为了你自己的目的,你自己 不能指望解析器提供它。在这种情况下,请定义自己的错误处理程序 并使用不同的名称。
完成所有这些后,您的程序将使用您的{{1}}进行编译。无论是否按预期工作,我都说不出来。