我正在尝试开发一个基本的编译器,我使用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。)
答案 0 :(得分:2)
没有。如果您使用%union
声明,则不得#define YYSTYPE
;野牛手册清楚地说明了这一点。
但是,任何必要的声明 - 在这种情况下,struct info
的声明 - 也必须包含在词法分析器描述文件(parse.l
)中。两个生成的文件彼此独立,因此{em>解析器中声明struct info
的事实不会使词法分析器自动使用该定义。 / p>
为了避免重复声明,通常最好将它们放在单独的头文件中:
#ifndef INFO_H_HEADER_
#define INFO_H_HEADER_
struct info {
int line;
/* details unimportant */
};
// ...
#endif
%{
#include <stdio.h>
#include <string.h>
#include "info.h"
%}
%union{
char *str;
struct info *ptr;
}
%{
#include <stdio.h>
#include <string.h>
/* This must come *before* including parse.tab.h */
#include "info.h"
#include "parse.tab.h"
%}
答案 1 :(得分:0)
以下是我如何使用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
答案 2 :(得分:0)
您的关联代码的问题在于%union
里面的 <。em文件顶部的%{
... %}
- 这意味着yacc只是将其逐字复制到y.tab.c文件中,并且实际上并不处理它。
当您尝试编译%union
时,这显然表现为y.tab.c
上的语法错误,但也意味着YYSTYPE
中没有y.tab.h
定义,因为yacc没有'看到%union
所以没有创建一个。