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 生成的解析器希望您定义两个函数,yylex
和yyerror
。 (通常,您使用 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
,如果您的实现包含它,我建议您也这样做。 )
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 生成的解析器希望您定义两个函数,yylex
和yyerror
。 (通常,您使用 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
,如果您的实现包含它,我建议您也这样做。 )