Надеюсь, на это не ответил, трудно прочитать похожие вопросы, потому что все они, похоже, касаются разработки iOS в Xcode. Я пишу парсер и нуждаюсь в заголовке, включенном как в мою грамматику (.y), так и в мои файлы lexer (.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
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 { $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;
}
Makefile
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
не определено *! = Un * указанный *. – immibis
при компиляции любые параметры библиотек '-ll' игнорируются (и их вообще не должно быть) – user3629249
при написании шагов компиляции (эти вызовы $ (CC) с параметром' -c', если вы включили ' -o outputname', тогда было бы очевидно, что в корне проблемы. В общем случае лучше всего попытаться скомпилировать один файл при вызове $ (CC) с параметром '-c'.' ' build', compile' не создают файл с тем же именем, поэтому в начале make-файла должен быть оператор:. .PHONY: build compile' – user3629249