在Bison / Yacc的%union def中包含struct

时间:2009-09-16 01:01:07

标签: c yacc bison

我试图将一个结构作为Bison与union的一部分包含在内,但是我在%union中的'struct node args'上得到了一个错误:

parser.y:17: error: field ‘args’ has incomplete type

守则:

struct node {
    char * val;
    struct node * next;
};

%}

%union {
    char * string;
    struct node args;
}

%token <string> CD WORD PWD EXIT

%type <args> arg_list

任何人都知道我做错了什么?

3 个答案:

答案 0 :(得分:25)

更好的是,使用带有“requires”选项的%code指令,即:

%code requires {
    struct node {
        char * val;
        struct node * next;
    };
}

%union {
    char * string;
    struct node args;
}

这将包括tab.h文件中“requires”块中的代码以及解析器源文件。

来自文档:http://www.gnu.org/software/bison/manual/html_node/Decl-Summary.html#Decl-Summary

  
      
  • 需要   
        
    • 目的:这是编写所需的依赖项代码的最佳位置   YYSTYPE和YYLTYPE。换一种说法,   这是定义类型的最佳位置   在%union指令中引用,和   这是超越的最佳场所   野牛的默认YYSTYPE和YYLTYPE   定义
    •   
  •   

答案 1 :(得分:15)

归结为你得到的跛脚y.tab.h输出。

您需要通过确保在任何地方包含y.tab.h之前定义“struct node”来解决此问题。

为此,请使用结构定义创建一个文件node.h。

然后在您的parser.l文件,parser.y文件以及包含y.tab.h的任何c文件中的y.tab.h之前包含node.h.这有点烦人。

或者你可以将“struct node args”更改为“struct node * args”,因为在你去某个地方使用它之前你不需要知道完整的类型。不确定这是否适合您的代码。

任何一个都应该工作。

答案 2 :(得分:1)

也许更简单(我认为) - 自己使用它:

%union {
  char   c; 
  struct {
     char name[30];
     int  type;
  } s;
}

然后,在flex中你可以使用&#34; yylval.s.name&#34; ,或者&#34; yylval.s.type&#34;等等。在野牛中,而不是$$=0, $1=bla ...你现在可以写$<s.type>$=0 , $<s.type>1=bla...