Hello world Flex/Bison 解析器生成一堆警告消息...如何摆脱它们?

Hello world Flex/Bison parser generates a bunch of warning messages ... how to get rid of them?

Flex/Bison这里是新手。

我正在尝试创建一个你好世界lexer/parser。当我 运行 解析器时,我希望它从命令行读取。如果我输入:

Hello, World

然后我希望解析器打印出这个 XML:

<Document>Hello, World</Document>

这是我的词法分析器 (helloworld.l)

%{
#include "helloworld.tab.h"
%}

%%
.+              { yylval = yytext; return(DATA); }
\n              { return(EOL); }
%%
int yywrap(){ return 1;}

这是我的解析器 (helloworld.y)

%{
#include <stdio.h>
%}

%token DATA
%token EOL

%%
start: /* nothing */
 | data EOL { printf("<Document>%s</Document>\n> ", ); }
 ;

data: DATA     { $$ = ; }
 ;
%%

int main()
{
  printf("> "); 
  yyparse();
  return 0;
}

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

这是我的 Makefile

main: helloworld.l helloworld.y
    ..\..\win_bison -d helloworld.y
    ..\..\win_flex helloworld.l
    gcc -o $@ helloworld.tab.c lex.yy.c

当我 运行 make 时,我收到以下警告消息。他们的意思是什么?我该如何修复它们?

helloworld.tab.c: In function 'yyparse':
helloworld.tab.c:576:16: warning: implicit declaration of function 'yylex' [-Wimplicit-function-declaration]
  576 | # define YYLEX yylex ()
      |                ^~~~~
helloworld.tab.c:1236:16: note: in expansion of macro 'YYLEX'
 1236 |       yychar = YYLEX;
      |                ^~~~~
helloworld.tab.c:1378:7: warning: implicit declaration of function 'yyerror'; did you mean 'yyerrok'? [-Wimplicit-function-declaration]
 1378 |       yyerror (YY_("syntax error"));
      |       ^~~~~~~
      |       yyerrok
helloworld.y: At top level:
helloworld.y:24:1: warning: return type defaults to 'int' [-Wimplicit-int]
   24 | yyerror(char *s)
      | ^~~~~~~
helloworld.l: In function 'yylex':
helloworld.l:6:10: warning: assignment to 'YYSTYPE' {aka 'int'} from 'char *' makes integer from pointer without a cast [-Wint-conversion]
    6 | .+              { yylval = yytext; return(DATA); }
      |          ^

自从 C 允许未声明 [​​=45=] 类型的函数(如您的 yyerror)以来已有 20 多年了,这表明您使用的是 非常 老例子作为模板。我强烈建议你看看examples in the Bison manual。尽管它们没有显示与 flex 的集成,但它们将在现代 C 编译器上毫无怨言地进行编译。

编写该示例时,returned int 的函数根本不声明可能是可以接受的,但在本世纪,您需要为它之前的每个函数提供声明被使用了。

bison 生成的解析器希望您定义两个函数,yylexyyerror。 (通常,您使用 flex 生成 yylex 但这与 bison 无关,因为扫描器是单独编译的。)您必须在生成的解析器的序言中声明这些函数(您也将#include 用于您的操作需要的任何库函数的指令)。

对于简单的解析器,声明可能是:

%{
#include <stdio.h>
int yylex(void);
void yyerror(const char* msg);
%}

请注意,我通过添加const更改了yyerror的参数声明,这将符合现代风格(因为参数可能是字符文字,yyerror不能尝试修改它)。这将与以下实现一致:

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

除此之外,您必须修复扫描器操作,因为您不应依赖扫描器 return 之后的 yytext 值。 (更准确地说,该值将在下一次调用 yylex 时改变,但允许解析器提前读取,而且经常这样做。)所以如果你想将它传递给,你必须复制 yytext解析器:

.+      { yylval = malloc(yyleng + 1);
          strcpy(yylval, yytext);
          return(DATA); }

(我写出来是因为您似乎在使用 Windows;通常情况下,我只会使用 strdup,如果您的实现包含它,我建议您也这样做。 )