Makefile for sql parser... writing dependencies

523 views Asked by At

I'm implementing a sql parser in lex and yacc, in that I use a symbol table which I kept in a separate .h file (sql.h) and in this header file I have some functions declarations. The definitions of these functions are kept in a .c file (sql.c). Now I have included sql.h in sql.c, I refer to the symbols and functions from sql.h in both my lex file(1.l) and yacc file(1.y).

The problem is that I'm not able to write a proper makefile for this. I'm getting errors like multiple declarations. Where do I include which file and how to write dependencies? Please help. I have searched for a solution but I'm not getting it.....

Update:

I compile the code like this:

lex 1.l
yacc -d 1.y
gcc lex.yy.c y.tab.c sql.c -ll -ly

I get the following errors after the third command of gcc:

In file included from 1.l:5:
sql.h:17: warning: ‘SQL’ initialized and declared ‘extern’
sql.h:18: warning: ‘SQL_SEL’ initialized and declared ‘extern’
1.l: In function ‘makeTable’:
1.l:80: warning: assignment from incompatible pointer type
In file included from 1.y:7:
sql.h:17: warning: ‘SQL’ initialized and declared ‘extern’
sql.h:18: warning: ‘SQL_SEL’ initialized and declared ‘extern’
sql.c:3: error: redefinition of ‘SQL’
sql.h:15: note: previous definition of ‘SQL’ was here
sql.c:4: error: redefinition of ‘SQL_SEL’
sql.h:16: note: previous definition of ‘SQL_SEL’ was here

sql.h:

#ifndef SQL_H
#define SQL_H
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

struct sym_table {
    char *token;
    char *value;
    struct sym_table *next;
};

struct sym_select {
    char **cols;        
};

extern struct sym_table *SQL = NULL;
extern struct sym_select *SQL_SEL = NULL;


void addSymbol(char *, char *);
void print(struct sym_table *);
void showTable(struct sym_table *);
void makeTable(struct sym_table *, int);

sql.c:

#include "sql.h"

struct sym_table *SQL = NULL;
struct sym_select *SQL_SEL = NULL;

And the definitions of the functions declared in sql.h

1.l file:

%{
    #include <stdio.h>
    #include <stdlib.h>
    #include "y.tab.h"
    #include "sql.h"
    int lineno=1;
    void makeTable(struct sym_table *, int);    
%}

..... and othr lex file

1.y

%{
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    extern int lineno;
    extern void yyerror(char *);
    #include "sql.h"
%}

.... and other yacc file data


Can you suggest me some other way to get around this?

2

There are 2 answers

3
AudioBubble On BEST ANSWER

Please post your Makefile. As far as i understand there's also a problem with code, not only with Makefile. Or it could be that you try to make 1.o from 1.l and different 1.o from 1.y.

Normally the dependencies should look something like:

1l.o: 1.l sql.h; # lex invocation
1y.o: 1.y sql.h; # bison invocation
sql.o: sql.c sql.h; # cc invocation
prog: 1l.o 1y.o sql.o; # ld invocation

Probably you will also need to depend on tokens' declaration file.

EDIT: Ah, so probably you need to put the definition of that table into one file, and the declaration into the header. You must first understand the difference between declaration and definition in C. For example if you have the following files:

aaa.h
int arr[]={1};

aaa.c
#include "aaa.h"

bbb.c
#include "aaa.h"

And then you try to cc -o aaa aaa.c bbb.c, you get the multiple definition error. That means, that the actual array must be in one file, and in the header it should be something like extern int arr[];

Update:

You should remove setting to NULL in sql.h. It's only a declaration there, that there is such and such variable somewhere. The actual value is to be assigned in sql.c.

1
Maxim Egorushkin On
extern struct sym_table *SQL = NULL;
extern struct sym_select *SQL_SEL = NULL;

Remove the initialization = NULL from the header file.