Reputation: 293
I'm trying to develop a basic compiler and I'm using a union for yylval
as follows:
%{
#include <string.h>
#include <stdio.h>
struct info {
int line;
/* details unimportant */
};
%}
%union{
char *str;
struct info *ptr;
}
In my lexer definition, I have
%{
#include "parse.tab.h"
%}
But when I compile the generated lexer, I get the following errors:
y.tab.h: unknown type name 'YYSTYPE'.
error: request for a member str in something not a structure or a union.
Do I need to #define YYSTYPE
as well?
(I edited the original question to insert enough information from the source files to make the question answerable. Any mistakes in the transcription are my fault and I apologize -- Rici.)
Upvotes: 2
Views: 3967
Reputation: 241861
No. If you use a %union
declaration, you must not #define YYSTYPE
; the bison manual makes this clear.
However, any necessary declarations -- in this case, the declaration of struct info
-- must be included in your lexer description file (parse.l
) as well. The two generated files are independent of each other, so the fact that struct info
is declared in the parser does not make the definition automatically available to the lexer.
In order to avoid repeating the declarations, it is usually a good idea to put them in a separate header file:
#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"
%}
Upvotes: 3
Reputation: 126408
The problem with your linked code is that the %union
is inside the %{
...%}
at the top of your .y file -- which means that yacc just copies it verbatim to the y.tab.c file and does not actually process it.
This manifests most obviously as a syntax error on %union
when you try to compile y.tab.c
, but also means there's no YYSTYPE
definition in y.tab.h
, as yacc didn't see the %union
so didn't create one.
Upvotes: 0
Reputation: 25286
The following is an example of how I use 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
Upvotes: 0