2010-07-21 37 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