yacc - field has incomplete type - c

yacc doesn't seem to like when my tokens are of a type that I defined.
At the top of my grammar (.y) file in a %{ ... %} block, I include a header file that defines the following structure:
typedef struct _spim_register {
spim_register_type type; /* This is a simple enumeration, already defined */
int number;
} spim_register;
Before my list of rules, I have:
%token AREG
...
%union {
struct _spim_register reg;
}
...
%type <reg> register AREG
I get
error: field ‘reg’ has incomplete type
at the line in the %union clause while trying to compile the code produced by bison. In my %union statement, trying to declare reg by writing spim_register reg; gives the error:
unknown type name ‘spim_register’
It seems like there's something special about %union { ... }, because I'm able to use the data structures from my header file in the actions for the rules.

It would help if my #includes were in the right order...
The answer was, as user786653 hinted, here. I needed to include the header file that defines my custom structure before including the .tab.h file in the .l file.

I met the same problem. Because my *.l file like this:
include "y.tab.h"
include "FP.h"
then, I rewrote it like this:
include "FP.h"
include "y.tab.h"
It works. Thank you very much. #ArIck

Related

Why is bison include not applying/extending to union%?

So here is the start of my program. I keep getting the error
boolExpr.y:13:2: error: unknown type name 'bool'
bool boolean;
However when I check the bison generated file, I can see stdbool.h is included at the start of the program executing. I can't figure out how a library can be important but then bool not be recognized. I'm thinking I missed something simple, or I need to reinstall bison or lex. I can include the rest of the program if needed.
I tried to switch it to int boolean; instead of bool boolean; and that fixed the compilation problem, however it still mystifies me.
Is there some way to extend a pointer to a struct into %union without getting compile errors? I tried to make a structName * boolean; to replace bool boolean but that kept coming back as undefined wimplicit error as well.
%{
#include "semantics.h"
#include <stdbool.h>
#include "IOMngr.h"
#include <string.h>
extern int yylex(); /* The next token function. */
extern char *yytext; /* The matched token text. */
extern int yyerror(char *s);
extern SymTab *table;
extern SymEntry *entry;
%}
%union{
bool boolean;(this is the line # of error)
char * string;
}
%type <string> Id
%type <boolean> Expr
%type <boolean> Term
%type <boolean> Factor
%token Ident
%token TRUE
%token FALSE
%token OR
%token AND
%%
Prog : StmtSeq {printSymTab();};
StmtSeq : Stmt StmtSeq { };
StmtSeq : { };
Stmt : Id '=' Expr ';' {storeVar($1, $3);};
Expr : Expr OR Term {$$ = doOR($1, $3);};
Expr : Term {$$ = $1;};
Term : Term AND Factor {$$ = doAND($1, $3);};
Term : Factor {$$ = $1;};
Factor : '!' Factor {$$ = doNOT($2);};
Factor : '(' Expr ')' {$$ = $2;};
Factor : Id {$$ = getVal($1);};
Factor : TRUE {$$ = true;};
Factor : FALSE {$$ = false;};
Id : Ident {$$ = strdup(yytext);};
%%
int yyerror(char *s) {
WriteIndicator(getCurrentColumnNum());
WriteMessage("Illegal Character in YACC");
return 1;
}
Ok, silly mistake after all- in my lex file, I had
#include "h4.tab.h"
#include "SymTab.h"
#include <stdbool.h>
but it should have been
#include "SymTab.h"
#include <stdbool.h>
#include "h4.tab.h"
didn't realize include order mattered!
When you use a %union declaration, Bison creates a union type called YYSTYPE which it declares in the generated header file; that type is used in the declaration of yylval, which is also in the generated header file. Putting the declarations in the generated header file means that you don't need to do anything to make yylval and its type YYSTYPE available in your lexical analyser, other than #includeing the bison-generated header file.
That's fine if all the types referred to in the %union declaration are standard C types. But there is a problem if you want to use a type which requires an #included header file, or which you yourself define. Assuming you put the necessary lines in a bison code prologue (%{...}%) before the %union declaration, you won't have a problem compiling your parser, but you will run into a problem in the lexical analyser. When you #include your header file, you will effectively insert the declaration of ´union YYSTYPE´ and that will fail unless all of the referenced types have already been defined.
Of course, you can solve this issue by just copying all the necessary #includes and/or definitions from the .y file to the .l file, making sure that you put the ones needed for the union+ declaration before the #include of the header file and the ones which require YYSTYPE be defined after the #include. But that violates the principles of good software design; it means that every time you change an #include or declaration in your .y file, you need to think about whether and where you need to make a similar change in your .l file. Fortunately, bison provides a more convenient mechanism.
The ideal would be to arrange for everything needed to be inserted into the generated header file. Then you can just #include "h4.tab.h" in the lexical analyzer, confident that you don't need to do anything else to ensure that needed #includes are present and in the correct order.
To this end, Bison provides a more flexible alternative to %{...}%, the %code directive:
%code [where] {
// code to insert
}
There are a few possible values for where, which are documented in the Bison documentation.
Two of these are used to maintain the generated header file:
%code requires { ... } inserts the code block in both the header file and the source file, in both cases before the union declaration. This is the code block type you should use for dependencies of the semantic and location types.
%code provides { ... } also inserts the code block into both the header and the source file, but this time after the union declaration. You can use this block type if you have some interfaces which themselves refer to YYSTYPE.
You can still use %{...}% to insert code directly into the output source code. But you might want to instead use
* %code { ... }
which, like %{...}%, only inserts the code in the source file. Unlike %{...}%, it inserts the code in a defined place in the source file, after the YYSTYPE and other declarations. This avoids obscure problems with %{...}% blocks, which are sometimes inserted early and sometimes inserted late and therefore can suddenly fail to compile if you change the order of apparently unrelated bison directives.

yydestruct too few arguments to function call (flex&bison)

I'm trying to make a reentrant flex&bison parser but I got this strange error:
too few arguments to function call, expected 5, have 4
I can see that the code generated by Bison looks like this:
static void
yydestruct (const char *yymsg,
yysymbol_kind_t yykind, YYSTYPE *yyvaluep, void *scanner, struct BisonOutput *out)
{ ...some code... }
and
int
yyparse (void *scanner, struct BisonOutput *out)
{
...some code...
yydestruct ("Cleanup: discarding lookahead",
yytoken, &yylval, out); // <--- here void*scanner parameter is clearly missing
...some code...
}
My code is this:
%define api.pure full
%lex-param {void *scanner}
%parse-param {void *scanner, struct BisonOutput *out}
%{
struct BisonOutput{
int out;
};
#include "syntax_parser.h"
#include "lex.yy.h"
#include <stdio.h>
%}
%define api.value.type union
%token <int> NUM
...bunch of other tokens...
%%
...bunch of grammar rules...
%%
... main function and such ...
And Flex code is as follows:
%{
#include "syntax_parser.h"
%}
%option reentrant bison-bridge noyywrap
blanks [ \t\n]+
number [0-9]+
%option noyywrap
%%
... bunch of rules ...
I'm really lost. Why doesn't bison plug scanner into yydestruct despite clearly using it in yyparse?
You are not allowed to put two parameters in a %*-param declaration. The correct way to produce the set of parameters you want is:
%param { void* scanner }
%parse-param { struct BisonOutput* out }
Bison doesn't really parse the code between { and }. All it does is identify the last identifier which it assumes is the name of the parameter. It also assumes that the code is a syntactically-correct declaration of a single parameter, and it is inserted as such in the prototypes. Since it's actually two parameters, it can be inserted without problem into a prototype, but since only one argument is inserted into the calls to the function, these don't match the prototype.
(Really, void* scanner should be yyscan_t scanner, with a prior typedef void* yyscan_t;. But perhaps it is not really better.)
You might also consider putting the declaration of struct BisonOutput into a %code requires (or %code provides) block, so that it is automatically included in the bison-generated header file.

How to compile a yacc file that contains a header file [duplicate]

I wrote bison code header:
%{
#include "foo.h"
%}
And I defined a struct named 'Foo' in header. I'd like to use it as token type in Bison.
%define api.value.type union
%token <Foo*> bar
Then I use -d option to generate bison.tab.h file.
bison -d bison.y
But there is no #include foo.h in bison.tab.h, and it use struct Foo to define the union YYSTYPE.
//bison.tab.h
union YYSTPE {
Foo* bar;
...
};
It caused error when compile this program: error: ‘Foo’ does not name a type
Is there a way to include header file in bison.tab.h or another solution of this case?
For includes that should appear in both the .c and the .h file (before the definition for the %union), you should use %code requires { ... }. %{ ... } inserts code in the .c file only.
For more information on the various %code options, you can look at the "Prologue Alternatives" chapter of the Bison docs.
I needed to use 2.3 bison version, which doesn't have %code directive, so I just added a command which insert my include into top of bison output header, when I compile program
echo #include \"my_include.hpp\" | cat - ${BISON_HEADER_OUTPUT} > tmp && mv tmp ${BISON_HEADER_OUTPUT}

Enum declaration not found when including containing header

I have an enumerator type that is declared in a header file. I would like to use this in a c file that includes this header file. However when compiling I get an error that the enumerator type is not defined. I've tried copying the enumerator declaration to my source file but I get an error: "nested redefinition of ‘enum command_type’"
Could someone explain how to use the enumerator type in my file please?
Thank you!
The enumerator:
//command-internals.h
enum command_type
{
AND_COMMAND, // A && B
SEQUENCE_COMMAND, // A ; B
OR_COMMAND, // A || B
PIPE_COMMAND, // A | B
SIMPLE_COMMAND, // a simple command
SUBSHELL_COMMAND, // ( A )
};
The usage:
//#include "command-internals.h"
command_type scan(char *buffer)
...
The error: error: unknown type name ‘command_type’
Your prototype should read:
enum command_type scan(char *buffer);
Since you didn't put a typedef on the enum declaration.
With your code compiler cannot understand what is the the type of command_type.
One will typically use a typedef:
//Header file
typedef enum {....} command_type;
//C File
command_type scan(char *buffer)
With this you don't have to remember to keep adding an enum everywhere again.

Wrapping C structs with SWIG

I have C header file containing the following type definition:
// example.h
typedef struct Vertex {
int color;
} Vertex;
I try to wrap this struct with SWIG, but apparently I am doing something wrong. My SWIG interface file looks like
// example.i
%module example
%inline %{
#include "example.h"
}
But if I copy the contents of my header file into my interface file so that the latter looks like
%module example
%inline %{
typedef struct Vertex {
int color;
} Vertex;
%}
I can access the struct from Ruby in the following way
irb> require 'example'
# => true
irb> Examlpe::Vertex
# => Vertex
Is there a way to automatically wrap a header file? I don't want to copy and paste the contents of the header file to the interface file every time I change it.
Thanks in advance for your help.
-- t6d
It's been a while since I used Swig but as I recall %inline is used to pass through the inline part directly to the compiler; Swig itself doesn't see it, What I think you need is:
%module example
%include<example.h>

Resources