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

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}

Related

Redefinition error while accessing a global variable defined in executable from library

I have static library file(lib_XXX.a) with global variable defined in it. I am trying to access the global variable in my executable(exe_XXX.o).
Linker error is coming. Any help would be thankful.
Languae : c
OS : Ubuntu gcc compiler
Sample as follows
exe_xxx.o module has 2 files resource.h and main.c
resource.h code as follows :
#ifndef RESOURCE_H
#define RESOURCE_H
#define APL
extern const StructTest g_AplObjDef;
const StructTest g_AplObjDef = {
abc, def, ghi,
....
};
#endif //APL
main.c code as follows:
#include "resource.h"
....
....
....
lib_xxx.a has another main.c in it. Its sample code as follows:
#include "resource.h"
int main()
{
#if defined(APL)
fun1(g_AplObjDef);
#endif
}
I suspect the reason is because resource.h included in both the main.c files.
I couldn't way to get rid of this. Can anyone help ?
Error details:
/lib_XXX.a(lib_XXX_a-main.o):(.data.rel.ro.local+0x40): `g_AplObjDef' が重複して定義されています
/exe_xxx-main.o:(.data.rel.ro.local+0x260): ここで最初に定義されています
Above error is in Japanese.. 1st line says "Duplicate is defined". 2nd line says "Here it is defined"
This part:
const StructTest g_AplObjDef = {
abc, def, ghi,
....
};
is a definition, and should not be in a header. Move it to
a .c file.
The reason for this is that header files are textually inserted, so if a header has a definition, and is included from multiple translation units, the symbol will be defined multiple times, which is an error.
Here you are defining a variable in the header
const StructTest g_AplObjDef =
You should only declare, which you did the line before.
This definition should go into a code file, accessing it will be possible by the knowledge provded by the declaration in the header. But the definition in the header will be done in each code file which includes it, which causes the redundant definition mentioned in the error message.
Moving the definition (as you now have it in the header, including the {...} into the libs code file should help.
Note that having two main() will probably get you into trouble, I only focus this answer on the double definition of the variable.

include header files in C

I am a newbie to C and C++ language, I have a question about header files in C:
a.h
#define HELLO (1)
typedef struct
{
int a;
int b;
} hello;
b.h
#include "a.h"
#define NUMBER (3)
main.c
#include "b.h"
in main.c, does struct and macro defined in a.h can be used in main.c?
Sure you can use both Struct and MACROS in the main.c
You need to be aware of the C Compilation Process, Before main.c is being compiled or linked, there is the pre-processor step:
Preprocessor:
The input to this phase is the .c File and .h Files
The preprocess process the preprocessor keywords like #define, #ifdef, #include, etc. and generate a new .pre file or .i file after the text replacement process.
The output of this phase is a C Code without any preprocessor keyword.
So the main.c will actually look like this:
#define HELLO (1)
typedef struct
{
int a;
int b;
} hello;
#define NUMBER (3)
And then replace all macros, here you don't use HELLO or NUMBER, so the pure c main file will be:
typedef struct
{
int a;
int b;
} hello;
Yes, it can be used. That is the sole purpose of #includeing of header files.
For more information, you can see the preprocessed version of code. Use
gcc -E <filename.c> //main.c, in this case
There you can see the presence of the struct and MACROS definde in the included header files.
Yes, #include directives themselves appearing in included files have their normal effect, up to an implementation-defined limit on the number of levels of inclusion. The "normal effect" is equivalent to textual interpolation -- that is, there is no separate scoping for the contents of included files -- so any declaration appearing in any directly or indirectly included file is visible to all code following the point of inclusion.
Yep, #include statements can chain multiple files together. #include literally copies and pastes the contents of one file into another, so you can think of it as a one-after-another effect.

Get the included path in same program

Suppose I have a program
main.c
#include "file.h"
#include <stdio.h>
int main()
{
//Code to found the included path
}
gcc -I /local main.c
How can I found the included path of header file inside this program
Now their can be 3 included path
current directory
ENV set in the Path VARIABLE or other
Directory included with -I option
Please provide a way to get this inside the same program.
For the include files that you could edit you can use the __FILE__ macro. It makes the preprocessor insert the full file's name like /the/directory/filename.
Just add the follow line to you header:
static const char MyIncludeFileName[] = __FILE__;
If you do not refer to MyIncludeFileName (from the code which includes the header) the compiler might issue a warning that MyIncludeFileName is declared but not used. To tell the compiler be quiet about this do the followings:
static const char MyIncludeFileName[] __attribute__ ((unused)) = __FILE__;

yacc - field has incomplete type

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

Typedef issue with bison and flex

In my parser, I have
%union {
SYMTABLE *p_entry ;
QUAD *p_quad ;
} ;
Now, SYMTABLE is the typedef for a struct. The struct and typedef are in an included file. There are no issues with this.
QUAD is the typedef for a struct (typedef struct quad QUAD). The struct and typedef are in an included file.
There is no problem doing:
bison -d parser.y
gcc parser.tab.c -c
My lexer needs yylval, so in the declarations part I have
#include "parser.tab.h" /* bison generated header file */
extern YYSTYPE yylval ;
When I do
flex scanner.lex
gcc lex.yy.c -c
GCC complains
In file included from scanner.lex:16:
parser.y:30: error: syntax error before "QUAD"
parser.y:30: warning: no semicolon at end of struct or union
parser.y:32: error: syntax error before '}' token
parser.y:32: warning: data definition has no type or storage class
parser.tab.h:121: error: syntax error before "yylval"
parser.tab.h:121: warning: data definition has no type or storage class
If I go back to my parser.y file and replace QUAD with struct quad in ONLY the yylval %union, the problem goes away. I want to say this is a silly typedef mistake, but the bison generated file compiles just fine. I have included the header file for my QUAD typedef and struct quad in my scanner.
It seems this is the only place where the issues occurs, so I could just replace QUAD with struct quad, but this is inconsistent with the SYMTABLE.
my test.l:
%{
#include "bla.h"
#include "test.tab.h" /* bison generated header file */
extern YYSTYPE yylval ;
%}
%%
\n printf("nl");
. printf("c");
%%
my test.y:
%{
#include "bla.h"
%}
%union {
SYMTABLE *p_entry ;
QUAD *p_quad ;
};
%%
input:
| input;
%%
my bla.h:
typedef void *SYMTABLE;
typedef void *QUAD;
my build:
freundt#segen:pts/21:~/temp> bison -d test.y
test.y: conflicts: 1 shift/reduce
test.y:13.3-7: warning: rule useless in parser due to conflicts: input: input
freundt#segen:pts/21:~/temp> flex test.l
freundt#segen:pts/21:~/temp> icc lex.yy.c -c
freundt#segen:pts/21:~/temp>

Resources