2
votes

I am working on Lex and Yacc program but I am getting error as :

/tmp/ccTP9YY1.o: In function yylex': lex.yy.c:(.text+0x289): undefined reference toyylval' lex.yy.c:(.text+0x2a8): undefined reference to `yylval' collect2: error: ld returned 1 exit status

I have searched a lot on Internet like stackoverflow and other sites but none of them seems to capable of solving my problem. I might be implementing those suggestions incorrectly. Can anyone please suggest me anything about this ? Thanks in advance.

%{
#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;
}

Commands used :

rohit@rohit-HP-Pavilion-g4-Notebook-PC:~$ lex echo.l
rohit@rohit-HP-Pavilion-g4-Notebook-PC:~$ yacc -d yaccCalc.y 
rohit@rohit-HP-Pavilion-g4-Notebook-PC:~$ gcc lex.yy.c y.tab.h -ll
/tmp/ccTP9YY1.o: In function `yylex':
lex.yy.c:(.text+0x289): undefined reference to `yylval'
lex.yy.c:(.text+0x2a8): undefined reference to `yylval'
collect2: error: ld returned 1 exit status

Yacc file :

%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;
}
2
You need to link the scanner with the parser (because yylval is defined in the parser). I'm certain that that is what the other answers say, but it is not possible to tell what error you made in attempting to accomplish it unless you reveal the precise commands you used to compile and link your project. - rici
sorry I did'nt put it. Now I've edited with commands and yacc file - Rohit Kesarwani
Change y.tab.h to y.tab.c in the gcc command. Compiling a header file doesn't do what you think it does, and it wouldn't help even if it did because the definition of yylval is not in the header file, only the declaration. (You already #include the header file generated in lex.yy.c, so yylval is declared. The linker error is because it is never defined.) - rici

2 Answers

2
votes

You should compile the .c file, not the .h file. Below is the command you need to compile your lex and yacc program:

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

Two files are generated by Yacc (and Bison), namely y.tab.h and y.tab.c assuming you do not override the output file with option -o. Include y.tab.h in your source code and compile y.tab.c. So perhaps you made a typo when trying to compile:

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