Неопределенная ссылка на `yylval 'и` yyerror` - PullRequest
0 голосов
/ 07 февраля 2019

Я пытаюсь скомпилировать пример из книги flex and Bison.Мне было интересно, почему я получил следующую ошибку сборки, и как я могу ее исправить?

$ make
bison -d fb1-5.y
fb1-5.y: warning: 3 shift/reduce conflicts [-Wconflicts-sr]
flex fb1-5.l
cc -o  fb1-5.tab.c lex.yy.c -lfl
fb1-5.l: In function ‘yylex’:
fb1-5.l:27:3: warning: implicit declaration of function ‘yyerror’; did you mean ‘perror’? [-Wimplicit-function-declaration]
 . { yyerror("Mystery character %c\n", *yytext); }
   ^~~~~~~
   perror
/tmp/cctl5WLj.o: In function `yylex':
lex.yy.c:(.text+0x32f): undefined reference to `yylval'
lex.yy.c:(.text+0x363): undefined reference to `yyerror'
collect2: error: ld returned 1 exit status
Makefile:2: recipe for target 'fb1-5' failed
make: *** [fb1-5] Error 1

Makefile:

fb1-5:  fb1-5.l fb1-5.y
    bison -d fb1-5.y
    flex fb1-5.l
    cc -o  fb1-5.tab.c lex.yy.c -lfl

fb1-5.y

/* simplest version of calculator */

%{
#  include <stdio.h>
%}

/* declare tokens */
%token NUMBER
%token ADD SUB MUL DIV ABS
%token OP CP
%token EOL

%%

calclist: /* nothing */
 | calclist exp EOL { printf("= %d\n> ", $2); }
 | calclist EOL { printf("> "); } /* blank line or a comment */
 ;

exp: factor
 | exp ADD exp { $$ = $1 + $3; }
 | exp SUB factor { $$ = $1 - $3; }
 | exp ABS factor { $$ = $1 | $3; }
 ;

factor: term
 | factor MUL term { $$ = $1 * $3; }
 | factor DIV term { $$ = $1 / $3; }
 ;

term: NUMBER
 | ABS term { $$ = $2 >= 0? $2 : - $2; }
 | OP exp CP { $$ = $2; }
 ;
%%
main()
{
  printf("> "); 
  yyparse();
}

yyerror(char *s)
{
  fprintf(stderr, "error: %s\n", s);
}

fb1-5.l:

/* recognize tokens for the calculator and print them out */

%{
# include "fb1-5.tab.h"
%}

%%
"+" { return ADD; }
"-" { return SUB; }
"*" { return MUL; }
"/" { return DIV; }
"|"     { return ABS; }
"("     { return OP; }
")"     { return CP; }
[0-9]+  { yylval = atoi(yytext); return NUMBER; }

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

Ответы [ 3 ]

0 голосов
/ 08 февраля 2019

Здесь есть две отдельные проблемы.

  1. yyerror не объявлено в вашем сканере (или, для этого mattet в вашем парсере).Bison не генерирует объявление для него, поэтому вам нужно объявить его в любом модуле перевода, который его использует.

  2. cc -o fb1-5.tab.c lex.yy.c -lfl говорит компилятору C скомпилировать lex.yy.c, поместив полученный исполняемый файл(вывод компилятора) в fb1-5.tab.c.Это не то, что вы хотели.Он перезаписывает сгенерированный синтаксический анализатор исполняемым файлом и не компилирует сгенерированный синтаксический анализатор, в результате чего символы, определенные в синтаксическом анализаторе, не доступны компоновщику.

0 голосов
/ 08 февраля 2019

Вы должны изменить свой make-файл на:

fb1-5:  fb1-5.l fb1-5.y
    bison -b fb1-5 -d fb1-5.y
    flex fb1-5.l
    gcc -o fb1-5 fb1-5.tab.c lex.yy.c -lfl -ly

, чтобы получить правильный выходной файл и иметь стандартную реализацию yyerror

0 голосов
/ 08 февраля 2019

Я полагаю, что проблема здесь

cc -o   lex.yy.c  fb1-5.tab.c -lfl
...