Makefile для sql parser ... написание зависимостей - PullRequest
0 голосов
/ 27 февраля 2011

Я реализую синтаксический анализатор sql в lex и yacc, в котором я использую таблицу символов, которую я храню в отдельном файле .h (sql.h), и в этом заголовочном файле у меня есть некоторые объявления функций.Определения этих функций хранятся в файле .c (sql.c).Теперь я включил sql.h в sql.c, я ссылаюсь на символы и функции из sql.h как в моем файле lex (1.l), так и в файле yacc (1.y).

Проблемав том, что я не могу написать правильный make-файл для этого.Я получаю ошибки, как несколько объявлений.Куда мне включать, какой файл и как писать зависимости?Пожалуйста помоги.Я искал решение, но не получаю его .....

Обновление:

Я компилирую код следующим образом:

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

Я получаюследующие ошибки после третьей команды 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;

И определенияфункции, объявленные в файле sql.h

1.l:

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

..... и другие файлы

1.y

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

.... и другие данные из файла yacc


Можете ли вы предложить мне другой способ обойти это?

Ответы [ 2 ]

0 голосов
/ 01 марта 2011
extern struct sym_table *SQL = NULL;
extern struct sym_select *SQL_SEL = NULL;

Удалить инициализацию = NULL из заголовочного файла.

0 голосов
/ 27 февраля 2011

Пожалуйста, опубликуйте свой Makefile.Насколько я понимаю, есть проблема с кодом, а не только с Makefile.Или может случиться так, что вы попытаетесь сделать 1.o из 1.l и другие 1.o из 1.y.

Обычно зависимости должны выглядеть примерно так:

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

Возможновам также нужно будет зависеть от файла объявления токенов.

РЕДАКТИРОВАТЬ: Ах, так что, вероятно, вам нужно поместить определение этой таблицы в один файл, а объявление в заголовок.Сначала вы должны понять разницу между объявлением и определением в C .Например, если у вас есть следующие файлы:

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

aaa.c
#include "aaa.h"

bbb.c
#include "aaa.h"

И затем вы пытаетесь cc -o aaa aaa.c bbb.c, вы получите ошибку множественного определения.Это означает, что фактический массив должен быть в одном файле, а в заголовке он должен выглядеть примерно так: extern int arr[];

Обновление:

Вы должны удалить значение NULL в sql.h.Там только декларация, что где-то есть такая-то переменная.Фактическое значение должно быть присвоено в sql.c.

...