Makefile for sql parser ...编写依赖项

时间:2011-02-27 12:58:39

标签: c yacc lex symbol-table

我在lex和yacc中实现了一个sql解析器, 因为我使用了一个符号表,我保存在一个单独的.h文件(sql.h)中,在这个头文件中我有一些函数声明。 这些函数的定义保存在.c文件(sql.c)中。现在我在sql.c中包含了sql.h, 我在我的lex文件(1.l)和yacc文件(1.y)中引用了sql.h中的符号和函数。

问题是我无法为此编写正确的makefile。 我收到多个声明之类的错误。 我在哪里包含哪个文件以及如何编写依赖项? 请帮忙。我已经找到了解决方案,但我没有得到它......

更新

我编译代码如下:

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 :(得分:0)

请发布您的Makefile。据我所知,代码也存在问题,不仅仅是Makefile。或者您可能尝试从1.o 1.l1.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[];

更新

您应该在sql.h中将设置删除为NULL。它只是一个声明,在某处有这样的变量。实际值将在sql.c中分配。

答案 1 :(得分:0)

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

从头文件中删除初始化= NULL