Bison:如何解决这个''yylex()'错误的'太多参数'?

时间:2014-03-07 01:19:47

标签: c++ bison

我正在学习如何使用Flex和Bison。我用C ++编写了一个解析器。我得到它来编译,但是当我添加选项来跟踪令牌位置时,我得到一个错误。

这是一个产生相同错误的小例子:

lexer.l

%{
#include <stdio.h>
#include "parser.tab.h"
#define YY_USER_ACTION yylloc->first_line = yylloc->last_line = yylineno; \
    yylloc->first_column = yycolumn; \
    yycolumn += yyleng;

int yycolumn = 1;
extern "C" int yyparse();
%}

%option bison-locations
%option yylineno
%option noyywrap

NAT [0-9]+

%%

{NAT} { printf("NUM: %d\n", atoi(yytext)); return NUM; }

"\n"  yycolumn = 1;
.     

%%

int main (int argc, char **argv) {
    argc--, argv++;
    if (argc > 0)
       yyin = fopen(argv[0], "r");
    else
        yyin = stdin;
    yyparse();
}

parser.y

%{
#include <iostream>
#include <stdio.h>

#define YYSTYPE int
using namespace std;

void yyerror (char const*);
int  yylex ();
extern "C" int yyparse ();
%}

%locations
%pure-parser

%token NUM
%%

s : NUM ;

%%

void yyerror(char const* s) {
    fprintf(stderr, "%s\n", s);
}

生成文件

par: parser.tab.c lex.yy.c
    g++ lex.yy.c parser.tab.c -o par

parser.tab.c: parser.y
    bison -d parser.y

lex.yy.c: lexer.l
    flex lexer.l

当我尝试编译它时出现以下错误:

parser.tab.c: In function ‘int yyparse()’:
parser.tab.c:1314:16: error: too many arguments to function ‘int yylex()’
parser.y:9:6: note: declared here

我尝试将parser.y中yylex的声明更改为int yylex (YYSTYPE*, YYLTYPE*),但名称YYLTYPE超出了范围并尝试了一些更多但未成功的事情...... < / p>

它会在删除lexer.l中的#define YY_USER_ACTION ...%option bison-locations以及解析器中的%locations%pure-parser时进行编译。

我怎样才能让它发挥作用?

2 个答案:

答案 0 :(得分:0)

您正在使用C ++编译生成的文件,尽管它们是C文件。这通常有效,但yylex的声明存在问题。在C中,

int yylex();

yylex声明为函数,而不指定有关其参数列表的任何内容。 (int yylex(void)会声明它没有参数。)这在C ++中是不可能的,因此您需要提供精确的参数列表。不幸的是,在yylex被定义之前,包含YYLTYPE定义的代码块被插入到生成的代码中。

一个简单的解决方案是将YYLTYPE预先声明为不完整类型:

struct YYLTYPE;

允许您在YYLTYPE*的声明中使用yylexYYLTYPE最终将被声明为struct,除非您提供了自己的声明。

使用最新版本的野牛,您应该可以使用以下内容:

%code requires {
#include <iostream>
#include <stdio.h>

/* If you insist :) */
using namespace std;

}

%code provides {
void yyerror (char const*);
int  yylex (YYSTYPE*, YYLTYPE*);
extern "C" int yyparse ();
%}

(这很可能不是你想要的纯粹解析器。但它可能足以让你开始。)

答案 1 :(得分:0)

您正在使用bison选项%pure-parser,该选项会更改其调用yylex的方式。您需要将flex %option bison-bridge添加到.l文件中以获得flex以使用yylex的相同调用约定