2013-06-15 9 views
7

Sto provando a creare un compilatore per un mini linguaggio simile a Pascal. Sto usando Flex e Bison per questo e ho trovato questo errore. file diRiferimento indefinito a `_yyerror 'durante la compilazione con Flex e Bison

mio Flex:

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

Il mio file Bison:

%{ 
    #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: 
     INT 
     |LEFTPAR expression RIGHTPAR 
     |ID 
     ; 

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: 
     PLUS 
     |MINUS 
     ; 

mulOper: 
     MUL 
     |DIV 
     ; 

optionalSign: 
     addOper 
     | 
     ; 

%% 

int main(int argc, char **argv) 
      { 
      printf("TEST\n"); 

      }  

La serie di passi che è stato eseguito in:

$ ./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 
$ 

Qualche consiglio su cosa dichiarare e dove perché sembra che io abbia dichiarato qualcosa nel modo sbagliato!

+0

Puoi avere una libreria, '-ly' (' liby.a' o 'liby.so') che fornisce una versione di 'yyerror()' e 'main()'. Dovresti quindi aggiungere '-ly' alla riga di comando del collegamento. –

risposta

14

Non è sufficiente dichiarare yyerror. Devi fornire una definizione.

Il bison manual suggerisce la seguente come un'implementazione minima:

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

L'altro problema che hai è che scritto male strcpy nel file flex.

Più esattamente, l'altro problema rilevato dagli errori del linker è l'errore ortografico strcpy, perché il codice di copia non è corretto. Non tiene conto del byte NUL che deve terminare le stringhe. strcpy copierà quel byte, con il risultato che scriverà uno 0 nella memoria non allocato. Troverai molto più semplice usare strdup. (E non dimenticare che hai bisogno di free stringhe quando hai finito con loro.)

Problemi correlati