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 make a compiler for a mini Pascal-like language. I'm using Flex and Bison for this and I came up with this error.

My Flex file:

#include "y.tab.h" #include <stdlib.h> #include <string.h> #include <math.h> void yyerror(char *); [1-9][0-9]* { yylval.i = atoi(yytext); return INT; program return PROGRAM; or return OR; and return AND; not return NOT; if return IF; else return ELSE ; while return WHILE; "+" return PLUS; "-" return MINUS; "*" return MUL; "/" return DIV; "[" return LSB; "]" return RSB; "{" return LCB; "}" return RCB; "(" return LEFTPAR; ")" return RIGHTPAR; ":=" return ASSIGN; "==" return ISEQUAL; "<" return LTHAN; ">" return GTHAN; "<>" return NOTEQUAL; "<=" return LESSEQUAL; ">=" return GREATEREQUAL; [a-zA-z][a-z0-9]* { yylval.s = (char*)malloc(strlen(yytext)*sizeof(char)); strcopy(yylval.s,yytext); return ID; [ \t\n]+ /* eat up whitespace */ . yyerror("Unknown Character"); int yywrap(void) { return 1;

My Bison file:

#include <stdio.h> #include <string.h> int yylex(void); void yyerror(char *s); %union { int i; char *s; %token <i> INTEGERNUM %token PROGRAM; %token OR; %token AND; %token NOT; %token IF; %token ELSE; %token WHILE; %token PLUS; %token MINUS; %token MUL; %token DIV; %token LSB; %token RSB; %token LCB; %token RCB; %token LEFTPAR; %token RIGHTPAR; %token ID; %token INT; %token ASSIGN; %token ISEQUAL; %token LTHAN; %token GTHAN; %token NOTEQUAL; %token LESSEQUAL; %token GREATEREQUAL; program: PROGRAM ID block block: LCB sequence RCB sequence: statement ';' sequence | statement ';' bracketsSeq: LCB sequence RCB brackOrStat: bracketsSeq | statement statement: assignmentStat |ifStat |whileStat assignmentStat: ID ':=' expression ifStat: IF LEFTPAR condition RIGHTPAR brackOrStat elsepart elsepart: ELSE brackOrStat whileStat: WHILE LEFTPAR condition RIGHTPAR brackOrStat expression: optionalSign expression |expression addOper expression |term term: term mulOper term |factor factor: |LEFTPAR expression RIGHTPAR condition: condition AND condition |boolterm boolterm: boolterm OR boolterm |boolfactor boolfactor: NOT LSB condition RSB |LSB condition RSB |expression relationalOper expression relationalOper: ISEQUAL |LTHAN |GTHAN |NOTEQUAL |LESSEQUAL |GREATEREQUAL addOper: |MINUS mulOper: optionalSign: addOper int main( int argc, char **argv ) printf("TEST\n");

The series of steps I executed was:

$ ./bison.exe -dy comp.y
$ ./flex.exe comp.l
$ gcc -c -w lex.yy.c 
$ gcc -c -w comp.tab.c
$ gcc comp.tab.o lex.yy.o -o ex
comp.tab.o:comp.tab.c:(.text+0x4cd): undefined reference to `_yyerror'
comp.tab.o:comp.tab.c:(.text+0x61c): undefined reference to `_yyerror'
lex.yy.o:lex.yy.c:(.text+0x34a): undefined reference to `_strcopy'
lex.yy.o:lex.yy.c:(.text+0x362): undefined reference to `_yyerror'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/ld: lex.yy.o: bad reloc address                0x828 in section `.rdata'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/ld: final link failed: Invalid                operation
collect2: ld returned 1 exit status

Any advice as to what to declare and where cause there seems to be that I have declared something the wrong way!

You may have a library, -ly (liby.a or liby.so) which provides a version of yyerror() and main(). You'd then add -ly to the linking command line. – Jonathan Leffler Jun 16, 2013 at 3:37

It's not enough to declare yyerror. You must provide a definition.

The bison manual suggests the following as a minimal implementation:

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

The other problem you have is that you misspelled strcpy in your flex file.

More accurately, the other problem revealed by the linker errors is the misspelled strcpy, because your copying code is incorrect. It does not account for the NUL byte which must terminate strings. strcpy will copy that byte, with the result that it will write a 0 in unallocated storage. You'll find it much simpler to use strdup. (And don't forget that you need to free the strings when you're finished with them.)

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.