2013-06-15 37 views
7

Tôi đang cố tạo một trình biên dịch cho một ngôn ngữ giống như Pascal nhỏ. Tôi đang sử dụng Flex và Bison cho điều này và tôi đã đưa ra lỗi này.Tham chiếu không xác định đối với `_yyerror 'khi biên dịch với Flex và Bison

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; 
} 

tập tin Bison của tôi:

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

      }  

Một loạt các bước tôi thực hiện là:

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

Bất cứ lời khuyên như những gì để tuyên bố và nơi có vẻ như tôi đã tuyên bố điều gì đó sai trái!

+0

Bạn có thể có thư viện, '-ly' (' liby.a' hoặc 'liby.so') cung cấp một phiên bản 'yyerror()' và 'main()'. Sau đó bạn sẽ thêm '-ly' vào dòng lệnh liên kết. –

Trả lời

14

Không đủ để khai báo yyerror. Bạn phải cung cấp một định nghĩa.

Các bison manual gợi ý sau đây như một thực hiện tối thiểu:

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

Vấn đề khác mà bạn có là bạn sai chính tả strcpy trong file flex của bạn.

Chính xác hơn, sự cố khác được tiết lộ bởi lỗi trình liên kết là lỗi chính tả strcpy, vì mã sao chép của bạn không chính xác. Nó không tính đến byte NUL phải kết thúc chuỗi. strcpy sẽ sao chép byte đó, với kết quả là nó sẽ viết một 0 trong bộ nhớ chưa được phân bổ. Bạn sẽ tìm thấy nó đơn giản hơn nhiều để sử dụng strdup. (Và đừng quên rằng bạn cần phải free các chuỗi khi bạn kết thúc với chúng.)

Các vấn đề liên quan