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

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

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

解析器
%{
#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超出范围,并尝试了一些其他尝试,但均未成功...

当lexer.l中的#define YY_USER_ACTION ...%option bison-locations和parser.y中的%locations%pure-parser被删除时,它将进行编译。

我如何使它工作?

最佳答案

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

int yylex();

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

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

它使您可以在YYLTYPE*的声明中使用yylex。除非您提供了自己的声明,否则YYLTYPE最终将被声明为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 ();
%}

(这可能不是纯解析器所需要的。但这可能足以使您入门。)

关于c++ - 野牛:如何解决此 'too many arguments to function ‘int yylex()’错误?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22239614/

10-09 19:18