2013-07-08 49 views
0

我在野牛的yacc文件中有此代碼塊。這是來自Flex & Bison書的flex/bison代碼的代碼。該YACC代碼可以從https://github.com/GrooveStomp/Flex-Bison/blob/master/samples/purecalc.y與野牛生成的文件的循環依賴解析

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

問題上下載的是,我有一個編譯錯誤(Circular dependency resolution with bison generated file);它們是循環依賴的,因爲purecalc.lex.h取決於在purecalc.h文件中的pcdata,而purecalc.h依賴於對yyscan_t的purecalc.lex.h。

yyscan_t是defiend在purecalc.lex.h:

typedef void* yyscan_t; 

PCDATA定義如下:

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

我怎樣才能打破這種代碼依賴?我試圖將typedef void* yyscan_t;複製到yacc源文件中,但是我複製typedef時出現編譯錯誤。

回答

1

是的,在最近的野牛歷史上有一段時間,骨架文件發生了不兼容的變化,導致yyparse被宣佈得早得多,事實上在%{ %}部分的包含點之前。因此yyparse在包含purecalc.h之前正在聲明,這意味着pcdata尚未聲明yyparse已聲明。

一個簡單的解決方案是先移動#include purecalc.h,但這會產生一個不同的問題。 pcdata的實際定義需要在purecalc.lex.h中聲明的yyscan_tpurecalc.lex.h要求#YYSTYPE #defined,這發生在purecalc.tab.h。並且purecalc.tab.h聲明yyparse,這需要聲明pcdata

的圓只能通過向前聲明來解決:

struct pcdata; 

但是,有被執行#included purecalc.tab.h之前發生。

所以一個可能性是把這些三行早期purecalc.h

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

,然後取下多餘purecalc.tab.hpurecalc.lex.h從分別purecalc.lpurecalc.y,包括。 (另外,成爲purecalc.h的加入後衛將是一個非常好的主意)。

另一種可能性是將struct pcdata;直接放入purecalc.y。但是對於那個使用%{ %}塊還不夠好;必須在宣佈yyparse之前插入。爲此,你需要一個%code requires { }塊:

%code requires { 
    struct pcdata; 
} 

我試過了,它用bison 2.7編譯。如果您要使用第一個解決方案,則需要使用%code requires { }塊作爲#include purecalc.h,所以看起來並不一樣。