Undefined reference to yyparse (flex & bison)

匿名 (未验证) 提交于 2019-12-03 02:50:02

问题:

I'm attempting to learn some flex/bison, and I'm reading Flex & Bison by John Levine (O'Reilly). There is an example that I need to get running, however I can't get it to run as I get the following error:

/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 

I've got four source files:

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

To Build:

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 

I'm running Ubuntu 10.04 x64, with the packages 'flex' and 'bison' installed. Anyone know why this error is happening, and how to fix it? Thanks in advance :)

回答1:

Solved it, the command

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

Should be

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

Not sure why the book didn't specify that for the example.



回答2:

I read that chapter as well and I believe the author is indicating that the code should be put in a "Makefile" to automate the build process for said files.

The $@ is a variable expansion used in bash shell scripts (among other places) and probably does the same thing in make or is exactly the same thing that make is implementing.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!