2013-06-15 25 views
7

के साथ संकलित करते समय `_yyerror 'के अनिर्धारित संदर्भ मैं मिनी पास्कल जैसी भाषा के लिए एक कंपाइलर बनाने की कोशिश कर रहा हूं। मैं इसके लिए फ्लेक्स और बाइसन का उपयोग कर रहा हूं और मैं इस त्रुटि के साथ आया हूं।फ्लेक्स और बायसन

मेरे फ्लेक्स फ़ाइल:

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

मेरे बाइसन फ़ाइल:

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

      }  

कदम की श्रृंखला मैं मार डाला था:

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

क्या करने के लिए के रूप में किसी भी सलाह की घोषणा करने और जहां ऐसा लगता है कि मैंने कुछ गलत तरीके से घोषित किया है!

+0

आपके पास लाइब्रेरी हो सकती है, '-ly' ('liby.a' या' liby.so') जो प्रदान करती है 'yyerror()' और 'main()' का एक संस्करण। फिर आप लिंकिंग कमांड लाइन में '-ly' जोड़ देंगे। –

उत्तर

14

yyerror घोषित करने के लिए पर्याप्त नहीं है। आपको एक परिभाषा प्रदान करनी होगी।

bison manual एक न्यूनतम कार्यान्वयन के रूप में निम्नलिखित सुझाव देती है:

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

दूसरी समस्या आप है कि आप अपने फ्लेक्स फ़ाइल में strcpy गलत वर्तनी है।

अधिक सटीक रूप से, लिंकर त्रुटियों द्वारा प्रकट की गई दूसरी समस्या गलत वर्तनी strcpy है, क्योंकि आपकी प्रतिलिपि कोड गलत है। यह NUL बाइट के लिए खाता नहीं है जो स्ट्रिंग को समाप्त करना होगा। strcpy उस बाइट की प्रतिलिपि बनायेगा, जिसके परिणामस्वरूप यह 0 को आवंटित स्टोरेज में लिख देगा। strdup का उपयोग करने के लिए आपको यह बहुत आसान लगेगा। (और यह न भूलें कि आपको free स्ट्रिंग्स की आवश्यकता होती है जब आप उनके साथ समाप्त हो जाते हैं।)

संबंधित मुद्दे