Circular dependency resolution with bison generated file

限于喜欢 提交于 2020-01-16 12:18:35

问题


I have this code block in bison's yacc file. This is the code from the flex/bison code for Flex & Bison book. The yacc code can be downloaded from https://github.com/GrooveStomp/Flex-Bison/blob/master/samples/purecalc.y

%{
#  include "purecalc.lex.h"
#  include "purecalc.h"
#define YYLEX_PARAM pp->scaninfo
%}

The issue is that I have a compilation error(Circular dependency resolution with bison generated file); they are circular dependent as purecalc.lex.h depends on pcdata which is in purecalc.h file, whereas purecalc.h depends on purecalc.lex.h for yyscan_t.

yyscan_t is defiend in purecalc.lex.h:

typedef void* yyscan_t;

pcdata is defined as follows:

/* per-parse data */
struct pcdata {
  yyscan_t scaninfo;        /* scanner context */
  struct symbol *symtab;    /* symbols for this parse */
  struct ast *ast;      /* an AST for  */
};

How can I break this code dependency? I tried to copy the typedef void* yyscan_t; into the yacc source, but I got compilation error for duplicating typedef.


回答1:


Yes, some time in recent bison history, an incompatible change was made to the skeleton files, causing yyparse to be declared much earlier, in fact before the inclusion point for %{ %} sections. So yyparse is being declared before purecalc.h is included, which means that pcdata is not declared yet when yyparse is declared.

A simple solution would be to move the #include purecalc.h earlier, but this creates a different problem. The actual definition of pcdata requires yyscan_t which is declared in purecalc.lex.h. purecalc.lex.h requires that YYSTYPE be #defined, which happens in purecalc.tab.h. And purecalc.tab.h declares yyparse, which requires the declaration of pcdata.

The circularity can only be resolved by forward declaring:

struct pcdata;

But that has to happen before purecalc.tab.h is #included.

So one possibility would be to put these three lines early purecalc.h:

struct pcdata;
#include purecalc.tab.h
#include purecalc.lex.h

and then remove the redundant purecalc.tab.h and purecalc.lex.h includes from purecalc.l and purecalc.y, respectively. (Also, it would be a really good idea to be an include guard into purecalc.h).

Another possibility is to put struct pcdata; directly into purecalc.y. But it's not good enough to use a %{ %} block for that; it has to be inserted before yyparse is declared. For that, you need a %code requires { } block:

%code requires {
    struct pcdata;
}

I tried that, and it compiled with bison 2.7. If you were to use the first solution, you'd need to use a %code requires { } block for the #include purecalc.h, so it wouldn't look that different.



来源:https://stackoverflow.com/questions/17518961/circular-dependency-resolution-with-bison-generated-file

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!