当我似乎包含正确的 header 时,找不到符号错误
Symbols not found error when I appear to be including proper header
我希望这没有得到回答,很难阅读类似的问题,因为它们似乎都是关于 iOS 在 Xcode 中的发展。我正在编写一个解析器,需要在我的语法 (.y) 和词法分析器 (.l) 文件中包含一个 header。最初只包含 header 而未定义函数会产生重复符号错误。我阅读了一些关于 C++ 的内容,并尝试制作一个 header 文件和一个 cpp 文件。现在我得到 symbol(s) not found error
。我想我只需要比我更了解 C++ 的人的帮助。此外,我正在慢慢地将此代码从 C 转换为 C++,因此现在有一些 non-C++ 做事的方法。
准确的错误是:
Undefined symbols for architecture x86_64:
"symlook(char*)", referenced from:
yylex() in lex.yy.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [outfile] Error 1
symtab.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NSYMS 20
struct symtab
{
char *name;
// ptr to C function to call if this entry is a fucntion name
double (*funcptr)();
double value;
};
extern symtab table[];
struct symtab *symlook(char *s);
void addfunc(char *name, double (*func)());
symtab.cpp
#include "symtab.h"
symtab table[NSYMS];
struct symtab *symlook(char *s) {
char *p;
struct symtab *sp;
for(sp = table; sp < &table[NSYMS]; sp++) {
/* is it already here? */
if(sp->name && !strcmp(sp->name, s))
return sp;
if(!sp->name) { /* is it free */
sp->name = strdup(s);
return sp;
}
/* otherwise continue to next */
}
fprintf(stderr, "%s\n", "Too many symbols");
exit(1); /* cannot continue */
} /* symlook */
void addfunc(char *name, double (*func)())
{
struct symtab *sp = symlook(name);
sp->funcptr = func;
}
simple.l
%{
#include "y.tab.h"
#include <math.h>
#include "symtab.h"
%}
%%
"if" return IF;
"true" return TRUE;
"false" return FALSE;
([0-9]+|([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) {
yylval.dval = atof(yytext);
return NUMBER;
}
[ \t] ; /* ignore whitespace */
[A-Za-z][A-Za-z0-9]* {
yylval.symp = symlook(yytext);
return NAME;
}
"$" return 0; /* logical EOF */
\n |
. return yytext[0];
%%
simple.y
%{
#include "symtab.h"
#include "ast.h"
#include <string>
#include <stdio.h>
int yylex(void);
void yyerror(char *);
%}
%union {
double dval;
int ival;
struct symtab *symp;
}
%token <symp> NAME
%token <ival> INTEGER_LITERAL
%token <dval> NUMBER
%token IF TRUE FALSE WHILE
%left '-' '+'
%left '*' '/'
%nonassoc UMINUS
%type <dval> num_expression
%%
statement_list: statement '\n'
| statement_list statement '\n'
;
statement: NAME '=' num_expression { ->value = ; }
| num_expression { fprintf(stderr, "= %g\n", ); }
| if_expression
| bool_expression
| while_expression
;
num_expression: num_expression '+' num_expression { $$ = + ; }
| num_expression '-' num_expression { $$ = - ; }
| num_expression '*' num_expression { $$ = * ; }
| num_expression '/' num_expression
{
if( == 0.0)
yyerror("divide by zero");
else
$$ = / ;
}
| '-' num_expression %prec UMINUS { $$ = -; }
| '(' num_expression ')' { $$ = ; }
| NUMBER
| NAME { $$ = ->value; }
| NAME '(' num_expression ')' { } //$$ = (->funcptr()); }
;
bool_expression: FALSE
| TRUE
;
if_expression: IF '(' bool_expression ')' '{' statement '}'
| IF '(' ')' '{' '}'
;
while_expression: WHILE '(' bool_expression ')' '{' statement '}'
| WHILE '(' ')' '{' '}'
;
%%
void yyerror(char *str)
{
fprintf(stderr, "Error %s", str);
}
int main() {
yyparse();
return 0;
}
生成文件
CC=g++
outfile=simple
lexfile=simple
yaccfile=simple
outfile: compile
${CC} -o ${outfile}.out lex.yy.o y.tab.o -ll
compile: build
${CC} -c symtab.cpp
${CC} -c lex.yy.c y.tab.c -ll
build:
yacc -d ${yaccfile}.y
flex ${lexfile}.l
您的 compile: build
步骤生成了一个文件 symtab.o
,您没有将其包含在 link 行中。
这是一个很常见的错误。问题出在这里:
#include "y.tab.h"
#include <math.h>
#include "symtab.h"
- 在您的 Makefile 中,您需要首先执行
yacc's
命令,因为 yacc
正在生成您的 "y.tab.h"
文件。
- 你需要
#include "y.tab.h"
在所有其他包括之后!想想这个! y.tab.h
将包含 "symtab.h"
中的内容,但 Lex 不知道那是什么,因为您在 "y.tab.h"
. 之后包含了 "symtab.h"
所以记住: 你总是必须在所有其他包含之后包含 "y.tab.h"
以避免这个错误!
我希望这没有得到回答,很难阅读类似的问题,因为它们似乎都是关于 iOS 在 Xcode 中的发展。我正在编写一个解析器,需要在我的语法 (.y) 和词法分析器 (.l) 文件中包含一个 header。最初只包含 header 而未定义函数会产生重复符号错误。我阅读了一些关于 C++ 的内容,并尝试制作一个 header 文件和一个 cpp 文件。现在我得到 symbol(s) not found error
。我想我只需要比我更了解 C++ 的人的帮助。此外,我正在慢慢地将此代码从 C 转换为 C++,因此现在有一些 non-C++ 做事的方法。
准确的错误是:
Undefined symbols for architecture x86_64:
"symlook(char*)", referenced from:
yylex() in lex.yy.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [outfile] Error 1
symtab.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NSYMS 20
struct symtab
{
char *name;
// ptr to C function to call if this entry is a fucntion name
double (*funcptr)();
double value;
};
extern symtab table[];
struct symtab *symlook(char *s);
void addfunc(char *name, double (*func)());
symtab.cpp
#include "symtab.h"
symtab table[NSYMS];
struct symtab *symlook(char *s) {
char *p;
struct symtab *sp;
for(sp = table; sp < &table[NSYMS]; sp++) {
/* is it already here? */
if(sp->name && !strcmp(sp->name, s))
return sp;
if(!sp->name) { /* is it free */
sp->name = strdup(s);
return sp;
}
/* otherwise continue to next */
}
fprintf(stderr, "%s\n", "Too many symbols");
exit(1); /* cannot continue */
} /* symlook */
void addfunc(char *name, double (*func)())
{
struct symtab *sp = symlook(name);
sp->funcptr = func;
}
simple.l
%{
#include "y.tab.h"
#include <math.h>
#include "symtab.h"
%}
%%
"if" return IF;
"true" return TRUE;
"false" return FALSE;
([0-9]+|([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) {
yylval.dval = atof(yytext);
return NUMBER;
}
[ \t] ; /* ignore whitespace */
[A-Za-z][A-Za-z0-9]* {
yylval.symp = symlook(yytext);
return NAME;
}
"$" return 0; /* logical EOF */
\n |
. return yytext[0];
%%
simple.y
%{
#include "symtab.h"
#include "ast.h"
#include <string>
#include <stdio.h>
int yylex(void);
void yyerror(char *);
%}
%union {
double dval;
int ival;
struct symtab *symp;
}
%token <symp> NAME
%token <ival> INTEGER_LITERAL
%token <dval> NUMBER
%token IF TRUE FALSE WHILE
%left '-' '+'
%left '*' '/'
%nonassoc UMINUS
%type <dval> num_expression
%%
statement_list: statement '\n'
| statement_list statement '\n'
;
statement: NAME '=' num_expression { ->value = ; }
| num_expression { fprintf(stderr, "= %g\n", ); }
| if_expression
| bool_expression
| while_expression
;
num_expression: num_expression '+' num_expression { $$ = + ; }
| num_expression '-' num_expression { $$ = - ; }
| num_expression '*' num_expression { $$ = * ; }
| num_expression '/' num_expression
{
if( == 0.0)
yyerror("divide by zero");
else
$$ = / ;
}
| '-' num_expression %prec UMINUS { $$ = -; }
| '(' num_expression ')' { $$ = ; }
| NUMBER
| NAME { $$ = ->value; }
| NAME '(' num_expression ')' { } //$$ = (->funcptr()); }
;
bool_expression: FALSE
| TRUE
;
if_expression: IF '(' bool_expression ')' '{' statement '}'
| IF '(' ')' '{' '}'
;
while_expression: WHILE '(' bool_expression ')' '{' statement '}'
| WHILE '(' ')' '{' '}'
;
%%
void yyerror(char *str)
{
fprintf(stderr, "Error %s", str);
}
int main() {
yyparse();
return 0;
}
生成文件
CC=g++
outfile=simple
lexfile=simple
yaccfile=simple
outfile: compile
${CC} -o ${outfile}.out lex.yy.o y.tab.o -ll
compile: build
${CC} -c symtab.cpp
${CC} -c lex.yy.c y.tab.c -ll
build:
yacc -d ${yaccfile}.y
flex ${lexfile}.l
您的 compile: build
步骤生成了一个文件 symtab.o
,您没有将其包含在 link 行中。
这是一个很常见的错误。问题出在这里:
#include "y.tab.h"
#include <math.h>
#include "symtab.h"
- 在您的 Makefile 中,您需要首先执行
yacc's
命令,因为yacc
正在生成您的"y.tab.h"
文件。 - 你需要
#include "y.tab.h"
在所有其他包括之后!想想这个!y.tab.h
将包含"symtab.h"
中的内容,但 Lex 不知道那是什么,因为您在"y.tab.h"
. 之后包含了
"symtab.h"
所以记住: 你总是必须在所有其他包含之后包含 "y.tab.h"
以避免这个错误!