【问题标题】:Undefined reference to yyparse (flex & bison)对 yyparse 的未定义引用(flex & bison)
【发布时间】:2010-07-21 11:30:30
【问题描述】:

我正在尝试学习一些 flex/bison,我正在阅读 John Levine (O'Reilly) 的 Flex & Bison。我需要运行一个示例,但是由于出现以下错误,我无法使其运行:

/tmp/ccKZcRYB.o: In function `yylex':
fb3-1.lex.c:(.text+0x2bd): undefined reference to `yylval'
/tmp/cclBqnOk.o: In function `main':
fb3-1funcs.c:(.text+0x420): undefined reference to `yyparse'
collect2: ld returned 1 exit status

我有四个源文件:

fb3-1.h

/*
 * Declarations for calculator  fb3-1
 */

/* Interface to the lexer */
extern int yylineno; /* from lexer */
void yyerror(char *s, ...);

/* nodes in the abstract syntax tree */
struct ast {
    int nodetype;
    struct ast *l;
    struct ast *r;
};

struct numval {
    int nodetype;   /* type K for constant */
    double number;
};

/* build an AST */
struct ast *newast(int nodetype, struct ast *l, struct ast *r);
struct ast *newnum(double d);

/* evaluate an AST */
double eval(struct ast *);

/* delete and free an AST */
void treefree(struct ast *);

fb3-1.l

/* recognise tokens for the calculator */
%option noyywrap nodefault yylineno
%{
#include "fb3-1.h"
#include "fb3-1.tab.h"
%}

/* float exponent */
EXP     ([Ee][-+]?[0-9]+)

%%

"+" |
"-" |
"*" |
"/" |
"|" |
"(" |
")"     { return yytext[0]; }
[0-9]+"."[0-9]*{EXP}? |
"."?[0-9]+{EXP}? { yylval.d = atof(yytext); return NUMBER; }

\n      { return EOL; }
"//".*
[ \t]   { /* ignore whitespace */ }
.       { yyerror("Mystery character %c\n", *yytext); }
%%

fb3-1.y

/* calculator with AST */

%{
#include <stdio.h>
#include <stdlib.h>
#include "fb3-1.h"
%}

%union {
    struct ast *a;
    double d;
}

/* declare tokens */
%token <d> NUMBER
%token EOL

%type <a> exp factor term

%%
calclist: /* nothing */
| calclist exp EOL {
    printf("=%4.4g\n",eval($2));
    treefree($2);
    printf("> ");
  }

  | calclist EOL { printf("> "); } /* blank line or a comment */
  ;

exp: factor
 | exp '+' factor { $$ = newast('+', $1, $3); }
 | exp '-' factor { $$ = newast('-', $1, $3); }
 ;

factor: term
 | factor '*' term { $$ = newast('*', $1, $3); }
 | factor '/' term { $$ = newast('/', $1, $3); }
 ;

term: NUMBER { $$ = newnum($1); }
 | '|' term { $$ = newast('|', $2, NULL); }
 | '(' term { $$ = $2; }
 | '-' term { $$ = newast('M', $2, NULL); }
 ;

%%

fb3-1funcs.c

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "fb3-1.h"

struct ast * newast(int nodetype, struct ast *l, struct ast *r)
{
    struct ast *a = malloc(sizeof(struct ast));

    if(!a) {
        yyerror("out of space");
        exit(0);
    }

    a->nodetype = nodetype;
    a->l = l;
    a->r = r;
    return a;
}

struct ast * newnum(double d)
{
    struct numval *a = malloc(sizeof(struct numval));

    if(!a) {
        yyerror("out of space");
        exit(0);
    }

    a->nodetype = 'K';
    a->number = d;
    return (struct ast *)a;
}

double eval (struct ast *a)
{
    double v;

    switch(a->nodetype) {
        case 'K': v = ((struct numval *)a)->number; break;

        case '+': v = eval(a->l) + eval(a->r); break;
        case '-': v = eval(a->l) + eval(a->r); break;
        case '*': v = eval(a->l) + eval(a->r); break;
        case '/': v = eval(a->l) + eval(a->r); break;
        case '|': v = eval(a->l); if(v < 0) v = -v; break;
        case 'M': v = -eval(a->l); break;
        default: printf("internal error: bad node %c\n", a->nodetype);
    }
}

void treefree(struct ast *a)
{
    switch(a->nodetype)
    {
        /* two subtrees */
        case '+':
        case '-':
        case '*':
        case '/':
            treefree(a->r);

        /* one subtree */
        case '|':
        case 'M':
            treefree(a->l);

        /* no subtree */
        case 'K':
            free(a);
            break;

        default: printf("internal error: free bad node %c\n", a->nodetype);
    }
}

void yyerror(char *s, ...)
{
    va_list ap;
    va_start(ap, s);

    fprintf(stderr, "%d: error: ", yylineno);
    vfprintf(stderr, s, ap);
    fprintf(stderr, "\n");
}

int main ()
{
    printf("> ");
    return yyparse();
}

构建:

bison -d fb3-1.y
flex -ofb3-1.lex.c fb3-1.l
cc -o $@ fb3-1.tab.c fb3-1.lex.c fb3-1funcs.c

我正在运行 Ubuntu 10.04 x64,安装了软件包“flex”和“bison”。任何人都知道为什么会发生此错误,以及如何解决它?在此先感谢:)

【问题讨论】:

  • 嘿伙计,你从这个计算器得到正确的答案吗?它给了我奇怪的答案
  • @MohammadGhorbani 对不起,我不记得了!自 2010 年以来,我没有接触过任何 flex-bison 或与之相关的任何东西,所以现在所有这些对我来说都像是胡言乱语!

标签: bison flex-lexer


【解决方案1】:

解决了,命令

cc -o $@ fb3-1.tab.c fb3-1.lex.c fb3-1funcs.c

应该是

cc -o fb3 fb3-1.tab.c fb3-1.lex.c fb3-1funcs.c

不知道为什么书中没有为示例指定这一点。

【讨论】:

    【解决方案2】:

    我也读过那一章,我相信作者是在指出代码应该放在“Makefile”中以自动化所述文件的构建过程。

    $@ 是 bash shell 脚本(以及其他地方)中使用的变量扩展,可能在 make 中做同样的事情,或者与 make 正在实现的事情完全相同。

    【讨论】:

    • 不,shell 的$@ 表示“此脚本/函数的参数”,而 Make 的$@ 表示“当前目标”,此处意为fb3,确实。
    猜你喜欢
    • 2011-09-19
    • 2012-09-27
    • 2013-06-12
    • 2019-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-14
    相关资源
    最近更新 更多