私は lex と yacc で sql パーサーを実装しています。別の .h ファイル (sql.h) に保存されているシンボル テーブルを使用し、このヘッダー ファイルにはいくつかの関数宣言があります。これらの関数の定義は、.c ファイル (sql.c) に保持されます。これで、sql.c に sql.h を含めました。lex ファイル (1.l) と yacc ファイル (1.y) の両方で、sql.h のシンボルと関数を参照します。
問題は、このための適切なメイクファイルを作成できないことです。複数の宣言などのエラーが発生します。どのファイルをどこにインクルードし、依存関係をどのように記述するか? 助けてください。解決策を検索しましたが、わかりません.....
アップデート:
次のようにコードをコンパイルします。
レックス1.l yacc -d 1.y gcc lex.yy.c y.tab.c sql.c -ll -ly
gcc の 3 番目のコマンドの後に、次のエラーが表示されます。
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 ファイル データ
これを回避する別の方法を教えてもらえますか?