Compiler construction lex程序中对yylval的未定义引用

Compiler construction lex程序中对yylval的未定义引用,compiler-construction,flex-lexer,lex,Compiler Construction,Flex Lexer,Lex,我正在处理Lex和Yacc程序,但我得到的错误如下: /tmp/ccTP9YY1.o:在函数yylex'中: lex.yy.c:(.text+0x289):未定义对yylval'的引用 lex.yy.c:(.text+0x2a8):对“yylval”的未定义引用 collect2:错误:ld返回了1个退出状态 我在互联网上搜索了很多,比如stackoverflow和其他网站,但似乎没有一个能解决我的问题。我可能没有正确地实施这些建议。有人能给我提些建议吗? 提前谢谢 %{ #include &l

我正在处理Lex和Yacc程序,但我得到的错误如下:

/tmp/ccTP9YY1.o:在函数
yylex'中:
lex.yy.c:(.text+0x289):未定义对
yylval'的引用 lex.yy.c:(.text+0x2a8):对“yylval”的未定义引用 collect2:错误:ld返回了1个退出状态

我在互联网上搜索了很多,比如stackoverflow和其他网站,但似乎没有一个能解决我的问题。我可能没有正确地实施这些建议。有人能给我提些建议吗? 提前谢谢

%{
#include <stdlib.h>
#include "y.tab.h"
void yyerror(char *); 
%}
%%
[a-z]  {
      yylval = *yytext - 'a';
      return VARIABLE;
       }
[0-9]+ {
      yylval = atoi(yytext);
      return INTEGER;
   }
[-+()=/*\n] { return *yytext; }
[ \t]        ;
.  {  yyerror("invalid character");   }

%%

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

int yywrap(void) {
   return 1;
}
Yacc文件:

%token INTEGER VARIABLE
%left '+' '-'
%left '*' '/'

%{
   void yyerror(char *);
   int yylex(void);
   int sym[26];
%}

%%

program:
    program statement '\n'
    | 
    ;

statement:
    expr                      { printf("%d\n", $1); }
    | VARIABLE '=' expr       { sym[$1] = $3; }
    ;

expr:
    INTEGER
    | VARIABLE                { $$ = sym[$1]; }
    | expr '+' expr           { $$ = $1 + $3; }
    | expr '-' expr           { $$ = $1 - $3; }
    | expr '*' expr           { $$ = $1 * $3; }
    | expr '/' expr           { $$ = $1 / $3; }
    | '(' expr ')'            { $$ = $2; }
    ;

%%

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

int main(void) {
   yyparse();
   return 0;
}

Yacc(和Bison)生成两个文件,即
y.tab.h
y.tab.c
,前提是您不使用选项
-o
覆盖输出文件。在源代码中包含
y.tab.h
,并编译
y.tab.c
。因此,可能您在尝试编译时输入了一个错误:

gcc lex.yy.c y.tab.c -ll
-------------------^-------- compile y.tab.c, not y.tab.h

您应该编译
.c
文件,而不是
.h
文件。以下是编译lex和yacc程序所需的命令:

1. yacc -d yaccCalc.y
2. lex echo.l
3. cc lex.yy.c y.tab.c -ll -ly

您需要将扫描器与解析器链接(因为解析器中定义了
yylval
)。我肯定其他答案都是这么说的,但是如果你不透露你用来编译和链接你的项目的确切命令,就不可能知道你在试图完成它时犯了什么错误。现在,我已经使用命令和yacc文件在
gcc
命令中将
y.tab.h
更改为
y.tab.c
。编译头文件并不会执行您认为它可以执行的操作,即使它执行了,也不会有帮助,因为头文件中没有
yylval
的定义,只有声明。(您已经#包括在
lex.yy.c
中生成的头文件,因此声明了
yylval
。链接器错误是因为它从未定义过。)请为您的答案添加解释。完成。我应该解释一下。
1. yacc -d yaccCalc.y
2. lex echo.l
3. cc lex.yy.c y.tab.c -ll -ly