在 yacc 文件中使用 union

Using union in yacc file

我正在尝试开发一个基本的编译器,我正在为 yylval 使用一个联合,如下所示:

%{
#include <string.h>
#include <stdio.h>
struct info {
  int line;
  /* details unimportant */
};
%}

%union{
  char *str;
  struct info *ptr;            
}

在我的词法分析器定义中,我有

%{
#include "parse.tab.h"
%}

但是当我编译生成的词法分析器时,出现以下错误:

y.tab.h:  unknown type name 'YYSTYPE'.
error: request for a member str in something not a structure or a union.

我也需要 #define YYSTYPE 吗?

(我编辑了原始问题,从源文件中插入了足够的信息,使问题可以回答。转录中的任何错误都是我的错,我深表歉意 -- Rici。)

以下是我如何使用 YYSTYPE 的示例:

typedef union {                         // base type filled by lexical analyzer
    struct {
        int numtype;                    // classval (type; selects into union below)
        union {
            int    ival;                    // integer value
            long   lval;                    // long value
            double dval;                    // double
        } val;
    } numval;
    unsigned char *sval;                    // string value
} lex_baseval;

typedef struct {                            // type returned by lexical analyzer
    int lineno;    
    lex_baseval lexval;
} YYSTYPE;

#define YYSTYPE YYSTYPE

没有。如果使用 %union 声明,则不得 #define YYSTYPE;野牛手册清楚地说明了这一点。

但是,任何必要的声明——在本例中为 struct info 的声明——也必须包含在词法分析器描述文件 (parse.l) 中。两个生成的文件相互独立,因此 parser 中声明 struct info 的事实不会使 lexer.

为了避免重复声明,通常最好将它们放在单独的头文件中:

文件:info.h(已添加)

#ifndef INFO_H_HEADER_
#define INFO_H_HEADER_
struct info {
  int line;
  /* details unimportant */
};
// ...
#endif

文件:parse.y(现在#include 的 info.h 而不是内联结构声明)

%{
#include <stdio.h>
#include <string.h>
#include "info.h"
%}
%union{
  char *str;
  struct info *ptr;
}

文件:parse.l(也#includes info.h)

%{
#include <stdio.h>
#include <string.h>
/* This must come *before* including parse.tab.h */
#include "info.h"
#include "parse.tab.h"
%}

您的链接代码的问题是 %union 内部 %{...%} 在您的顶部.y 文件——这意味着 yacc 只是将它逐字复制到 y.tab.c 文件,实际上并不处理它。

当您尝试编译 y.tab.c 时,这最明显地表现为 %union 上的语法错误,但也意味着 y.tab.h 中没有 YYSTYPE 定义,因为 yacc没有看到 %union 所以没有创建。