【问题标题】:I got an error in function `yylex': lex.yy.c:(.text+0x2ac): undefined reference我在函数“yylex”中遇到错误:lex.yy.c:(.text+0x2ac): undefined reference
【发布时间】:2018-03-27 08:14:48
【问题描述】:

我是 lex 和 yacc 的新手,我正在关注 "lex & yacc 1992" book

我正在编写第 3 章的示例,编译过程中出现错误,但找不到解决方案; 这是代码:

lex 文件.l :

%{

#include "y.tab.h"
#include "symboletable.h"
#include <math.h>
extern int yylavl;

%}


%%
([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]* { /* return symbol pointer */
            yylval.symp = symlook(yytext);
            return NAME;
        }
"$" { return 0; }
\n |  
. return yytext[0];

%%

这里是 yacc file.y

%{
#include "symboletable.h"
#include <string.h>
#include <stdio.h>     /* C declarations used in actions */
int yylex();
void yyerror(const char *s);
%}

%union {
    double dval;
    struct symtab *symp;
}

%token <symp> NAME
%token <dval> NUMBER

%left '+' '-'
%left '*' '/'
%nonassoc UMINUS

%type <dval> expression
%%

statement_list : statement '\n'
               | statement_list statement '\n'
               ;

statement  : expression   { printf("= %g\n", $1); } 
           | NAME '=' expression {$1->value = $3; }
           ;


expression : NAME {$$ = $1->value; }
           | expression '+' expression {$$ = $1 + $3; }
           | expression '-' expression {$$ = $1 - $3; }
           | expression '*' expression {$$ = $1 * $3; }
           | expression '/' expression
                {   if ($3 ==0.0)
                        yyerror("divide by zero");
                    else
                        $$ = $1 / $3; 
                }
           | '-' expression %prec UMINUS {$$ = -$2; }
           | '(' expression ')' {$$ = $2; }
           | NUMBER
           ;
%%

根据书中的例子,我需要写一个符号表例程,来获取字符串并为字符串分配动态空间,这里是file.h

符号表.h

#define NSYMS 20 /* maximum number of symbols */
struct symtab {
        char *name;
        double value;
} symtab[NSYMS];

struct symtab *symlook();

和 symboletable.pgm:

/* look up a symbol table entry, add if not present */
struct symtab *
symlook(s)
char *s;
{
    char *p;
    struct symtab *sp;
    for (sp = symtab; sp < &symtab[NSYMS]; sp++){
        /* is it already here ? */
        if (sp->name && !strcmp(sp->name, s))
            return sp;

        /* is it free */
        if (!sp->name){
            sp->name = strdup(s);
            return sp;
        }
        /* otherwise continue to next */
    }
    yyerror("Too many symbols");
    exit(1);    /* cannot continue */
} /* symlook */

现在当我运行以下命令时:

yacc -d file.y 
lex file.l 
cc -c lex.yy.c -o newfile -ll
cc -o new y.tab.c lex.yy.c -ly -ll

但我得到的错误是:

/tmp/ccGnPAO2.o:在函数yylex': lex.yy.c:(.text+0x2ac): undefined reference tosymlook'collect2:错误:ld返回1退出 状态

那么,为什么我得到了那个错误,我完全按照这个例子?

【问题讨论】:

  • 你为什么要写这么古老的代码?我完全迷失了你对symlook() 的定义。更新你的书。或者只有你的代码,参数声明的风格对你来说太旧了,你是新一代。
  • struct symtab *symlook(s) char *s { } is K&R C - ancient 是一个合适的描述。从 ANSI C 开始,这可以写为struct symtab* symlook(char *s) { }。关于原型struct symtab *symlook();:它可能有效,但更好的是具有正确签名的原型:struct symtab* symlook(char*);
  • 虽然 K&R C 很古老,但很多 C 编译器似乎仍然支持它。 (可能是对发明者的致敬......)我相信,语法不是你的问题。是什么让我怀疑:如果您的文件实现了 symlook() 真的被命名为 symboletable.pgm (就像您的问题中所述),那么您忘记在编译和链接行中提及它。因此,链接错误而不是语法错误。顺便提一句。 .pgm 不被禁止,但对于 c 源文件来说是不寻常的。为什么不用后缀.c
  • 您知道可以在.lex 文件的第二个%% 之后添加常规C 代码吗?如果您将 symlook() 的实现移到该位置,您的问题也应该得到解决。
  • 我对使用 lex 和 yacc 有点陌生,所以我不想让更改变得更糟,实际上我正在考虑在 lex 的第三部分将代码添加为普通的 c 样式文件,我只是想作为初学者按照书上的说明进行操作,好的,我将检查这些选项。

标签: c compiler-construction flex-lexer yacc lex


【解决方案1】:

您需要在编译命令中包含符号表实现。否则,链接器将如何找到该代码?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多