使用Bison/Yacc在%union定义中包含结构体

20

我尝试在Bison中将结构体包含在联合体中,但我在%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个回答

30

更好的做法是使用带有 "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

  • requires
    • 目的:在此处编写依赖于 YYSTYPE 和 YYLTYPE 的代码是最好的,换句话说, 这是定义在%union指令中引用的类型和 覆盖Bison默认的YYSTYPE和YYLTYPE 定义的最佳位置。

16

问题在于你得到的 y.tab.h 输出不够好。

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

为此,请创建一个名为 node.h 的文件,并在其中定义结构体。

然后,在你的 parser.l 文件、parser.y 文件以及包含 y.tab.h 的所有 c 文件之前包含 node.h。 这有点烦人。

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

两种方法都应该能够工作。


2
也许更简单(我认为) - 我自己使用了这个:
%union {
  char   c; 
  struct {
     char name[30];
     int  type;
  } s;
}

然后,在flex中,你可以使用"yylval.s.name"或"yylval.s.type"等等。而在bison中,你现在可以写成$<s.type>$=0,$<s.type>1=bla...,而不是$$=0,$1=bla


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接