当我看起来包含正确的标题时,未找到符号错误

时间:2016-01-28 01:17:19

标签: c++ c header-files bison flex-lexer

我希望这个问题没有得到解答,很难通过类似的问题阅读,因为它们似乎都与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

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

生成文件

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

2 个答案:

答案 0 :(得分:2)

您的compile: build步骤会生成一个您未包含在链接行中的文件symtab.o

答案 1 :(得分:0)

这是一个非常常见的错误。问题出在这里:

#include "y.tab.h"
#include <math.h>
#include "symtab.h"
  1. 在Makefile中,您需要先执行yacc's命令,因为yacc正在生成"y.tab.h"文件。
  2. 在所有其他内容之后,您需要#include "y.tab.h"!想想这个! y.tab.h会有来自"symtab.h"的内容,但Lex并不知道这是什么,因为"symtab.h"之后你已经"y.tab.h"了。
  3. 请记住: 您必须在所有其他包含后包含 "y.tab.h"以避免此错误!