【问题标题】:Makefile for sql parser... writing dependencies用于 sql 解析器的 Makefile... 编写依赖项
【发布时间】:2011-02-27 12:58:38
【问题描述】:

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

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

更新:

我这样编译代码:

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

gcc第三条命令后出现如下错误:

在 1.l:5 中包含的文件中: sql.h:17:警告:“SQL”已初始化并声明为“extern” sql.h:18:警告:“SQL_SEL”已初始化并声明为“extern” 1.l:在函数“makeTable”中: 1.l:80:警告:来自不兼容指针类型的赋值 在 1.y:7 包含的文件中: sql.h:17:警告:“SQL”已初始化并声明为“extern” sql.h:18:警告:“SQL_SEL”已初始化并声明为“extern” sql.c:3:错误:重新定义“SQL” sql.h:15:注意:“SQL”的先前定义在这里 sql.c:4:错误:重新定义“SQL_SEL” sql.h:16:注意:“SQL_SEL”的先前定义在这里

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);    
%}

..... 和其他 lex 文件

1.y

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

....和其他yacc文件数据


你能建议我用其他方法解决这个问题吗?

【问题讨论】:

    标签: c yacc lex symbol-table


    【解决方案1】:

    请发布您的 Makefile。据我了解,代码也存在问题,而不仅仅是Makefile。或者可能是您尝试从 1.l 制作 1.o 和从 1.y 制作不同的 1.o

    通常,依赖项应如下所示:

    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中赋值。

    【讨论】:

    • 实际上代码正在工作它只是将这些文件链接在一起的问题......我知道数据问题是数据在 sql.c 和 1.l(lex文件)和 1.y(yacc 文件).. dts y 符号表 n 它的对象在 sql.c den 1.l den in 1.y 中被多次声明... m nt 能够得到哪里 shud i inlcude wich 文件和 den 如何使用 wud d makefile .. 你建议的 makefile 是 wat 我写的 bt d 错误是 sql.h 中定义的符号的多个定义......
    • 是的... 1l.o 取决于 y.tab.c d 令牌声明文件.. 你能告诉我如何将所有这些文件链接在一起.. 我完全被困在这个..谢谢..)
    • 我已经发布了我的 src 文件.. 请看一下
    【解决方案2】:
    extern struct sym_table *SQL = NULL;
    extern struct sym_select *SQL_SEL = NULL;
    

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

    【讨论】:

    • 是的...做对了..删除了 d NULL 并且它起作用了.. 谢谢.. ))))
    猜你喜欢
    • 2013-04-27
    • 1970-01-01
    • 2016-09-14
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 2017-05-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多