2017-01-13 13 views
-1

나는 다음과 같은 코드에 대한 분할 오류 (코어 덤프) 받고 있어요 :다음 lex/yacc 파일에서 세그먼트 화 오류 (코어 덤프)가 수신됩니다. 그들에게 무슨 문제가 있습니까?

렉스 파일은 다음과 같다, test.l :

%{ 

    #include "y.tab.h" 

    #define LOOKUP 0 

    int state; 

    int add_word(int type, char *word); 
    int lookup_word(char *word); 
    %} 

    %% 

    \n {state = LOOKUP;} 
    \.\n {state = LOOKUP; 
      return 0; 
     } 

    ^verb {state = VERB;} 
    ^adj {state = ADJECTIVE;} 
    ^adv {state = ADVERB;} 
    ^noun {state = NOUN;} 
    ^prep {state = PREPOSITION;} 
    ^pron {state = PRONOUN;} 
    ^conj {state = CONJUNCTION;} 

    [a-zA-Z]+ { 
       if(state != LOOKUP){ 
        add_word(state, yytext); 
       }else{ 
        switch(lookup_word(yytext)){ 
         case VERB: return(VERB); 
         case ADJECTIVE: return(ADJECTIVE); 
         case ADVERB: return(ADVERB); 
         case NOUN: return(NOUN); 
         case PREPOSITION: return(PREPOSITION); 
         case PRONOUN: return(PRONOUN); 
         case CONJUNCTION: return(CONJUNCTION); 
         default: 
          printf("%s: don't recog\n",yytext); 
        } 
       } 
       } 
    . ; 

    %% 
    struct word{ 
     char *word_name; 
     int word_type; 
     struct word *next; 
    }; 

    struct word *word_list; 

    extern void *malloc(); 

    int add_word(int type, char *word){ 
     struct word *wp; 
     if(lookup_word(word) != LOOKUP){ 
      printf("word %s already defined\n", word); 
      return 0; 
     } 

     wp = (struct word *) malloc(sizeof(struct word)); 

     wp-> next = word_list; 

     wp-> word_name = (char*) malloc(strlen(word)+1); 
     strcpy(wp->word_name, word); 
     wp->word_type = type; 
     word_list = wp; 
     return 1; 
    } 

    int lookup_word(char *word){ 
     struct word *wp = word_list; 

     for(; wp; wp = wp->next){ 
     if(strcmp(wp->word_name, word) == 0) 
      return wp->word_type; 
     } 
     return LOOKUP; 
    } 

Yacc에 파일이 다음과 같다,

test.y :

%{ 

#include <stdio.h> 

%} 

%token NOUN PRONOUN VERB ADVERB ADJECTIVE PREPOSITION CONJUNCTION 

%% 
sentence: subject VERB object {printf("sentence is valid\n");} 
     ; 

subject: NOUN 
     | PRONOUN 
     ; 
object: NOUN 
     ; 

%% 

extern FILE *yyin; 

main(){ 
    while(!feof(yyin)){ 
     yyparse(); 
    } 
} 

yyerror(s) 
{ 
    fprintf(stderr, "some error\n"); 
} 

나는 문제가 무엇인지 알아 내려고 시간 동안 노력했습니다. 나는이 책을 완전히 새롭게하고 책 "O'reilly-Lex and Yacc"을 따른다.

+4

표준 함수의 프로토 타입 선언을 제공하지 말고 대신 올바른 헤더 파일을 포함하십시오. 또한 [malloc의 결과를 캐스팅하는 방법에 대한 설명] (http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc)을 읽어보십시오. –

+4

http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong – melpomene

+1

문제는 디버거에서 실행하면 충돌이 어디에서 발생합니까? 호출 스택에 코드가 있습니까? 그리고 충돌을 일으키기 위해 입력 한 내용을 포함하도록 질문을 편집하십시오. –

답변

1

입력을 수행하는 구성 요소는, 초기화 기능 중 각각 stdinstdoutyyin 및 초기화 yyout 인 (F) 렉스 의해 생성 스캐너. 그 전에는 C의 정적 초기화 규칙 (글로벌 포인터 변수가 NULL로 초기화 됨)의 결과로 NULL 포인터입니다.

yylex이 처음 호출되면 초기화 함수가 호출됩니다. (yylex에 대한 다음 호출을 다시 초기화를하지 않도록이 플래그를 설정 즉, 라이브러리 시스템을 초기화하는 매우 일반적인 방법이다;. 가장 malloc 구현하고, C stdio 일부 기능 구현이 같은 일을한다.)

yylexyyparse에 의해 반복적으로 호출되므로 yyparse에 대한 첫 번째 호출은 암시 적으로 yylex을 초기화합니다. 하지만 당신은 쓸 때 :이 초기화되기 전에

main(){ 
    while(!feof(yyin)){ 
    yyparse(); 
    } 
} 

yyin를 처음 사용할 때 발생합니다. 결과적으로 while 조건이 처음 평가 될 때 yyin은 여전히 ​​NULL이므로 두 번째 시간은 없습니다. 결과 segfault는 치명적입니다.

int main(){ 
    do yyparse(); while (!feof(yyin)); 
} 
: 그것은 말 루프의에서 EOF 테스트를 넣어 더 나을,

당신은 자신을 yyin를 초기화하여 그 문제를 해결 할 수 있지만 이후 while (!feof(file))은 항상 잘못 (SM)입니다

의 질문에 this very helpful SO answer을 참조하십시오. 왜 "while (!feof (file))"이 항상 잘못 되었습니까? 상세한 분석을 위해.

+0

고마워요! 이제는 더 이해가됩니다. D – user3470048