是否可以在 bison.y.h 文件中公开 yyin ?
Is it possible to expose yyin in the bison.y.h file?
我正在使用 flex 和 bison 构建一个编译器,但我需要将入口点放在一个附加文件中。
这给我带来了问题,因为我假装解析文件。
野牛文件如下所示:
%{
void set_file ( const char *file_path );
FILE *yyin;
%}
%%
// Boring stuff
%%
void set_file ( const char *file_path )
{
yyin = fopen(file_path, "r");
}
同时 'main.c' 文件如下所示:
#include "nml.y.h"
#include <stdio.h>
int main ( int argc, char *argv[] )
{
for (int i = 1; i < argc; i++) {
set_file(argv[i]);
yyparse();
}
return 0;
}
问题是 yyin 和 set_file() 都没有暴露在生成的 bison.tab.h 文件中,因为它们只是源文件的一部分,导致编译器警告,看起来是,一个非常糟糕的编程习惯。
有什么方法可以从另一个文件设置 yylexer 的输入吗?
首先,您要设置的 yyin
是由 flex 生成的扫描器声明和定义的。在 bison 生成的解析器中声明一个不同的变量将产生链接器错误,因为只能有一个具有给定名称的外部全局变量。所以你的野牛文件应该声明为 extern
.
但是您不想导出该声明;您要导出的唯一声明是 set_file
函数的声明。为了让 bison 将声明插入到头文件中,您需要将声明放在 %code provides
块中。
将所有这些放在一起,您会得到:
%code {
// Don't assume this file is included
#include <stdio.h>
}
%code provides {
void set_file ( const char *file_path );
}
%%
// Grammar
%%
void set_file ( const char *file_path )
{
/* Declare yyin, found in the scanner */
extern FILE* yyin;
yyin = fopen(file_path, "r");
}
当然,没有人真正关心您在哪里定义函数。您实际上不需要将 set_file
的定义放入解析器;您可以将它放在您的扫描仪中,您不需要 yyin
的外部声明(因为它已经在该文件中声明)。但是把声明放到bison生成的头文件里还是有用的。
我正在使用 flex 和 bison 构建一个编译器,但我需要将入口点放在一个附加文件中。 这给我带来了问题,因为我假装解析文件。
野牛文件如下所示:
%{
void set_file ( const char *file_path );
FILE *yyin;
%}
%%
// Boring stuff
%%
void set_file ( const char *file_path )
{
yyin = fopen(file_path, "r");
}
同时 'main.c' 文件如下所示:
#include "nml.y.h"
#include <stdio.h>
int main ( int argc, char *argv[] )
{
for (int i = 1; i < argc; i++) {
set_file(argv[i]);
yyparse();
}
return 0;
}
问题是 yyin 和 set_file() 都没有暴露在生成的 bison.tab.h 文件中,因为它们只是源文件的一部分,导致编译器警告,看起来是,一个非常糟糕的编程习惯。
有什么方法可以从另一个文件设置 yylexer 的输入吗?
首先,您要设置的 yyin
是由 flex 生成的扫描器声明和定义的。在 bison 生成的解析器中声明一个不同的变量将产生链接器错误,因为只能有一个具有给定名称的外部全局变量。所以你的野牛文件应该声明为 extern
.
但是您不想导出该声明;您要导出的唯一声明是 set_file
函数的声明。为了让 bison 将声明插入到头文件中,您需要将声明放在 %code provides
块中。
将所有这些放在一起,您会得到:
%code {
// Don't assume this file is included
#include <stdio.h>
}
%code provides {
void set_file ( const char *file_path );
}
%%
// Grammar
%%
void set_file ( const char *file_path )
{
/* Declare yyin, found in the scanner */
extern FILE* yyin;
yyin = fopen(file_path, "r");
}
当然,没有人真正关心您在哪里定义函数。您实际上不需要将 set_file
的定义放入解析器;您可以将它放在您的扫描仪中,您不需要 yyin
的外部声明(因为它已经在该文件中声明)。但是把声明放到bison生成的头文件里还是有用的。