Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm trying to create a very basic calculator using flex and bison. I'm a noob here tbh. So I create two files s1.l and s1.y. When I compile together but I get an error. Here is my code.

********** 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 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);

I expect it to work as simple calculator however it produces an error as follows :

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$

also I'm so sorry for the shitty formatting. I'm new to this platform.

I suppose you copied that out of some Makefile or something, but it's certainly not going to work as a shell command. In bash (or any other shell), $@ means "the arguments to the shell script", and since you're working in a console and not in a shell script, it is most likely that there are no arguments and $@ is empty. So after substitution, that command will read:

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

That is, it asks the compiler to compile the file generated by flex, and put the resulting executable in s1.tab.c, overwriting the file generated by bison. Since only the scanner is compiled, yylval is not found (it would have been defined in the parser). On the other hand, the fact that the parser was never compiled saves you from another problem you would otherwise have encountered: both of your files include a definition of main(). But an executable is only allowed to have one definition of main(). (Indeed, it can only have one definition of any external symbol, but main() is particularly important.)

Finally, as shown, your flex file s1.l will not produce correct results because the second and fourth lines (%{ and %}) are preceded by space characters. These markers must appear at the beginning of a line, without additional trailing characters. Text in the prologue preceded by whitespace is copied verbatim into the generated parser, and gcc would certainly produce a syntax error when it reads the %{. So I suppose that the files shown in your question do not precisely correspond to the files you are using.

I did what u said, I removed the white space, ran the correct gcc command but I'm still getting undefined reference to yylval. However if I remove the definiton of yylval from s1.l it compiles and run but doesn't display any output. Like if I type 5 + 6 and press enter it simply moves onto the next line without displaying = 11. – amit.s19 Dec 28, 2018 at 17:48 If the linker is complaining about a missing yylval definition and not complaining about a duplicate main definition, then you are not running the correct compilation command. (Possibly because you didn't recreate the bison output file which you overwrote with the incorrect compilation command.) – rici Dec 28, 2018 at 18:23

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.