Неопределенная ссылка на yylval в функции yylex (); - PullRequest
0 голосов
/ 28 декабря 2018

Я пытаюсь создать очень простой калькулятор, используя flex и bison.Я нуб здесь.Поэтому я создаю два файла s1.l и s1.y.Когда я собираю вместе, но я получаю ошибку.Вот мой код.

********** s1.l ********* 
/* Simple scanner in flex */
 %{
    # include "s1.tab.h"
 %}

%%

"+"     { return ADD; }
"-"     { return SUB; }
"*"     { return MUL; }
"/"     { return DIV; }
"|"     { return ABS; }
[0-9]+  { yylval = atoi(yytext); return NUMBER; }
\n      { return EOL; }
[ \t]   { }
.       { printf("Mystery character %c\n", *yytext); }

%%

int main(int argc, char *argv[] ) {
    while(yylex());
    return 0;
}

int yywrap() {
    return 1;
}

***** s1.y ******

%{
#include <stdio.h>   
%}

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

 %%
 calclist: 
 | calclist exp EOL { printf("= %d\n", $1); } 
 ;
 exp: 
 | exp ADD factor { $$ = $1 + $3; }
 | exp SUB factor { $$ = $1 - $3; }
 ;
 factor: 
 | factor MUL term { $$ = $1 * $3; }
 | factor DIV term { $$ = $1 / $3; }
 ;
 term: 
 | ABS term { $$ = $2 >= 0? $2 : - $2; }
 ;
 %%

 main(int argc, char **argv)
 {
  yyparse();
 }

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

Я ожидаю, что он будет работать как простой калькулятор, однако он выдаст ошибкуследующим образом:

satan@satan-GL63-8RC:~/Desktop/LEX$ bison -d s1.y
satan@satan-GL63-8RC:~/Desktop/LEX$ flex s1.l
satan@satan-GL63-8RC:~/Desktop/LEX$ gcc -o $@ s1.tab.c lex.yy.c
/tmp/cc85iL7m.o: In function `yylex':
lex.yy.c:(.text+0x31b): undefined reference to `yylval'
collect2: error: ld returned 1 exit status
satan@satan-GL63-8RC:~/Desktop/LEX$

также мне очень жаль дерьмовое форматирование.Я новичок в этой платформе.

1 Ответ

0 голосов
/ 28 декабря 2018

Одной из проблем является ваша команда компиляции:

gcc -o $@ s1.tab.c lex.yy.c

Полагаю, вы скопировали это из какого-то файла Makefile или чего-то еще, но она определенно не будет работать как команда оболочки.В bash (или любой другой оболочке) $@ означает «аргументы скрипта оболочки», и, поскольку вы работаете в консоли, а не в скрипте оболочки, наиболее вероятно, что аргументов нет и $@ пустой.Таким образом, после подстановки эта команда будет читать:

gcc -o s1.tab.c lex.yy.c 

То есть она просит компилятор скомпилировать файл, сгенерированный с помощью flex, и поместить полученный исполняемый файл в s1.tab.c, переписав файл, сгенерированный bison.Поскольку компилируется только сканер, yylval не найден (он был бы определен в анализаторе).С другой стороны, тот факт, что анализатор никогда не компилировался, избавляет вас от другой проблемы, с которой вы могли бы столкнуться в противном случае: оба ваших файла содержат определение main().Но исполняемый файл может иметь только одно определение main().(Действительно, он может иметь только одно определение любого внешнего символа, но main() особенно важен.)

Наконец, как показано, ваш гибкий файл s1.l не будет давать правильных результатов, поскольку второй и четвертыйперед строками (%{ и %}) ставятся пробелы.Эти маркеры должны появляться в начале строки без дополнительных завершающих символов.Текст в прологе, которому предшествует пробел, дословно копируется в сгенерированный синтаксический анализатор, и gcc, безусловно, выдаст синтаксическую ошибку при чтении %{.Поэтому я полагаю, что файлы, показанные в вашем вопросе, не совсем соответствуют файлам, которые вы используете.

...