是否可以在 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生成的头文件里还是有用的。