我希望这个问题没有得到解答,很难通过类似的问题阅读,因为它们似乎都与Xcode中的iOS开发有关。我正在写一个解析器,需要在我的语法(.y)和我的词法(.l)文件中包含一个头文件。最初只包括标题而没有定义函数给出了重复的符号错误。我在C ++上阅读了一些内容,并试图制作一个头文件和一个cpp文件。现在我得到symbol(s) not found error
。我想我只需要一些比我更了解C ++的人的帮助。此外,我正在慢慢地将此代码从C转换为C ++,因此现在有一些非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
#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)());
#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;
}
%{
#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];
%%
%{
#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 { $1->value = $3; }
| num_expression { fprintf(stderr, "= %g\n", $1); }
| if_expression
| bool_expression
| while_expression
;
num_expression: num_expression '+' num_expression { $$ = $1 + $3; }
| num_expression '-' num_expression { $$ = $1 - $3; }
| num_expression '*' num_expression { $$ = $1 * $3; }
| num_expression '/' num_expression
{
if($3 == 0.0)
yyerror("divide by zero");
else
$$ = $1 / $3;
}
| '-' num_expression %prec UMINUS { $$ = -$2; }
| '(' num_expression ')' { $$ = $2; }
| NUMBER
| NAME { $$ = $1->value; }
| NAME '(' num_expression ')' { } //$$ = ($1->funcptr($3)); }
;
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
答案 0 :(得分:2)
您的compile: build
步骤会生成一个您未包含在链接行中的文件symtab.o
。
答案 1 :(得分:0)
这是一个非常常见的错误。问题出在这里:
#include "y.tab.h"
#include <math.h>
#include "symtab.h"
yacc's
命令,因为yacc
正在生成"y.tab.h"
文件。 #include "y.tab.h"
!想想这个! y.tab.h
会有来自"symtab.h"
的内容,但Lex并不知道这是什么,因为"symtab.h"
之后你已经"y.tab.h"
了。 请记住: 您必须在所有其他包含后包含 "y.tab.h"
以避免此错误!