2014-12-21 8 views
0

내 세그먼트에이 세분화 오류가 있습니다. 첫 번째 변수 선언 바로 다음에 나타나는 것으로 보입니다. 모든 아이디어 어떻게이 오류를 제거 할 수 있습니까? 여기 내 코드의 일부입니다.세그먼트 오류 yacc/lex

렉스 파일 :

%{ 
#include <stdio.h> 
#include "comp-func.h" 
#include "y.tab.h" 
struct var *create_var(char *s); 
%} 

%% 

"int" {yylval.array = strdup(yytext); return INT;} 
0|-?[1-9][0-9]* {yylval.number = atoi(yytext); return INT_NO;} 
"main()" {yylval.array = strdup(yytext); return BGIN;} 
[_a-zA-Z][_a-zA-Z0-9]* {struct var *vr; 
      vr = create_var(yytext); 
      yylval.variable = vr; 
      return ID;} 
[ \t] ; 
\n {yylineno++;} 
. {return yytext[0];} 

%% 

struct var *create_var(char *s) 
{ 
    struct var *vr; 
    vr->var_value = 9999; 
    vr->var_name = strdup(s); 
    vr->next = NULL; 
    return vr; 
} 

은 yacc 파일 :

%{ 
#include <stdio.h> 
#include <string.h> 
#include "comp-func.h" 
extern FILE* yyin; 
extern char* yytext; 
extern int yylineno; 
void add_var(struct var *vari); 
void print_var(char *var); 
int lookup_var(char *var); 
%} 

%union { 
    int number; 
    char *array; 
    struct var *variable; 
} 

%token <array> INT 
%token <number> INT_NO 
%token <variable> ID 
%token <array> BGIN 
%start progr 

%left '-' '+' 
%left '*' '/' 

%type <number> expr 

%% 

progr: declaratii bloc {printf("ok\n");} 
    ; 

declaratii : declaratie_variabila ';' 
     | declaratii declaratie_variabila ';' 
     ; 

declaratie_variabila : INT ID {if(lookup_var($2->var_name)==0) 
            add_var($2); 
           else 
           { 
            printf("Variable -- %s -- is already defined\n",$2->var_name); 
            return 0; 
           } 
           } 
       ; 

/* bloc */ 
bloc : BGIN '{' list '}' 
    ; 

/* lista instructiuni */ 
list : statement ';' 
    | list statement ';' 
    ; 

/* instructiune */ 
statement : declaratie_variabila 
     | ID '=' expr {if(lookup_var($1->var_name)==0) 
      { 
       printf("Variable -- %s -- is not defined\n",$1->var_name); 
       return 0; 
      } 
      else $1->var_value = $3; 
      } 
      ; 

expr : INT_NO 
    | expr '+' expr  { $$ = $1 + $3; } 
    | expr '-' expr  { $$ = $1 - $3; } 
    | expr '*' expr  { $$ = $1 * $3; } 
    | expr '/' expr  { $$ = $1/$3; } 
    | '(' expr ')'  { $$ = $2; } 
    ; 

%% 

void add_var(struct var *vari) 
{ 
    struct var *vr; 

    vr->next = var_list; 

    strcpy(vr->var_name,vari->var_name); 

    vr->var_value = vari->var_value;  

    var_list = vr; 
} 

int yyerror(char * s){ 
printf("eroare: %s la linia:%d\n",s,yylineno); 
} 

int main(int argc, char** argv){ 
yyin=fopen(argv[1],"r"); 
yyparse(); 
} 
+0

아마도 'vr'은 yacc 파일에서 할당되지 않았습니다 (포인터 일 뿐이지 만 사용하고 있습니다). 어쨌든 - 디버거 (gdb, ddd 또는 유사한) 도움이됩니다. – kestasx

답변

2

create_var에서는 :

struct var *create_var(char *s) 
{ 
    struct var *vr; 
    vr->var_value = 9999; 

vr 당신이 메신저 다음 초기화되지 않으며, 할당 된 메모리를 가리키는 것처럼 그것을 사용하려고 시도합니다. 이는 초기화되지 않은 변수를 사용하는 정의되지 않은 동작이며 세그먼트 오류가 발생할 가능성이 큽니다. 또한

struct var *vr = malloc(sizeof *vr); 

:

  • 을 확인하기 위해 확인하는 것을 잊지 마세요 mallocNULL

  • 가 잊지 마세요 반환하지 않았습니다

    당신은 아마 같은 의미 당신이 그것을 할 때 할당 된 메모리를 무료로.

+0

그것은 일했다! 그러나 add_var ($ 2) 이후에이 함수에서 변수 "vr"에 대한 메모리를 할당 했음에도 불구하고 다시 세그먼테이션 오류가 발생합니다. – Andrew

+0

당신은'add_var'에서 같은 버그를 가지고 있습니다. – rici