2010-07-21 90 views
5

我试图学习一些flex/bison,并且我正在阅读John Levine(O'Reilly)的Flex & Bison。还有的是,我需要运行一个例子,但我不能让它跑,因为我得到以下错误:未定义的引用yyparse(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 [email protected] fb3-1.tab.c fb3-1.lex.c fb3-1funcs.c 

我运行Ubuntu 10.04 64位,包装'flex'和'野牛'安装。任何人都知道这个错误发生的原因,以及如何解决它?感谢提前:)

+0

嘿男人,你从这个计算器得到正确答案吗?它给我奇怪的答案 – 2016-05-02 22:25:57

+0

@MohammadGhorbani对不起,队友我不记得了!自2010年以来,我一直没有碰过任何弹性野牛或任何与之相关的东西,所以这些对我来说现在看起来就像是胡言乱语! – Tom 2016-05-04 11:08:26

回答

3

解决它,命令

cc -o [email protected] 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 

不知道为什么这本书没有指定的例子。

0

我也阅读了这一章,我相信作者指出应该将代码放在“Makefile”中以自动执行所述文件的构建过程。

$ @是用于bash shell脚本(以及其他地方)的变量扩展,可能在make中执行相同的操作,或者与make执行的操作完全相同。

+1

不,shell的'$ @'意味着“这个脚本/函数的参数”,而Make的'$ @'意味着“当前目标”,这里确实是'fb3'。 – akim 2012-11-14 08:23:12