代码之家  ›  专栏  ›  技术社区  ›  Kyle Brandt

在带有bison/yacc的%union def中包含结构

  •  17
  • Kyle Brandt  · 技术社区  · 15 年前

    我正在尝试将结构作为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 回复  |  直到 9 年前
        1
  •  23
  •   Mark    13 年前

    更好的是,使用带有“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指令中引用,以及 这是最好的地方 Bison的默认YYSTYPE和YYLTYPE 定义。
        2
  •  15
  •   tim    15 年前

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

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

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

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

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

    任何一个都应该工作。

        3
  •  1
  •   A Koscianski    9 年前

    可能更简单(我想)-我自己用过这个:

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

    然后,在flex中,您可以使用“yylval.s.name”或“yylval.s.type”等。在野牛中,而不是 $$=0, $1=bla …你现在可以写了 $<s.type>$=0 , $<s.type>1=bla...