2016-10-18 31 views
0

我正在学习野牛和遇到问题。我尝试设计一个RE来接受整数集,例如{1,2,3}。 以下是我的代码的一部分。在野牛中如何管理内存?

printf("given {, str_to_out before %s \n", str_to_out); 
str_to_out[0] = '{'; 
printf("given {, str_to_out after %s \n", str_to_out); 

问题是,当我输入“{1} - {2}”,一个简单的集计算,代码工作不正确。我得到两张照片如下:

given {, str_to_out before 
given {, str_to_out after {1} 

问题是什么?我认为这是因为内存管理有问题,也许我不明白。 谢谢大家帮助我! 其他代码如下所示: 该过程从函数“MinusPoly($$,$ 1,$ 3)”开始,然后按顺序: “Format()” - >“Expand()”。问题发生在“展开()”

%{ 
#define YYSTYPE char * 
#include <math.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#define MAXL 5000 
int yyerror(const char* s); 
int yylex(void); 
void MinusPoly(char *a,const char *p1, const char *p2); 
void Format(char* str); 
void AppendIntToStr(char* str, int num); 
void Expand(char* str); 
void RmRedunInt(char *str_to_out); 
void StrToIntList(char *str, int list[], int *count); 
int IsExist(int target, int list[], int length); 
void IntListToStr(char *str, int list[], int length); 
void RmWs(char* str); 
%} 
%token NUM 
%token LB RB POLY BRACE SET INTERSECT UNION MAX MIN 
%left '-' '+' 
%left '*' '/' DOTM 
%right '^' 
%% 
/* grammar rules and actions follow in {}*/ 

input: input line 
    | line 
    ; 

line: '\n' 
     | expr '\n' {printf("res %s\n",$1);} 
    ; 

expr: expr '-' expr_md {MinusPoly($$,$1,$3);} 
    | expr '+' expr_md {} 
    | expr_md {$$=$1;} 
    ; 

expr_md: expr_md '*' expr_hi {printf("multiply \n");} 
    | expr_md '/' expr_hi  {} 
    | expr_hi {$$=$1;} 
    ; 

expr_hi: LB expr RB {$$ = $2;} 
    | SET {printf("set %s\n",$1);} 
    ; 

%% 
#include<ctype.h> 
int main(void){ 
return yyparse(); 
} 
int yyerror(const char* s) { return 0; } 

void MinusPoly(char *a,const char *p1, const char *p2){ 
    int l1 = strlen(p1), l2 = strlen(p2); 
    int i; 
    char s, np1[MAXL],np2[MAXL]; 
    strcpy(np1,p1); 
    strcpy(np2,p2); 
    Format(np1); 
    Format(np2); 
    printf("np1 %s\n",np1); 
    printf("np2 %s\n",np2); 
    return; 
} 

void Format(char* str){ 
    char temp[MAXL]; 
    int i, j ,len; 
    strcpy(temp,str); 
    RmWs(temp); 
    Expand(temp); 
    len = strlen(temp); 
    printf("str is %s\n",temp); 
    for(i=0; i < len; i ++){ 
     str[i] = temp[i]; 
    } 
    str[i] = '\0'; 
    return; 
} 

void Expand(char* str){ 
    int i,j, len, outlen = 0, num1, num2,len1 = 0, len2 = 0,curr_num = 0; 
    char temp_sbl; 
    char str_to_out[MAXL], str_range[10], str_num[10]; 
    strcpy(str_to_out,""); 
    len = strlen(str); 
    printf("input str is %s, length %d\n",str,len); 
    if(len <= 2) 
     return; 
    for(i = 0 ;i < len; i ++){ 
     temp_sbl = str[i]; 
     if(temp_sbl == '{'){ 
printf("given {, str_to_out before %s \n", str_to_out); 
      str_to_out[0] = '{'; 
printf("given {, str_to_out after %s \n", str_to_out); 
      outlen++; 
      continue; 
     } 
     if(temp_sbl == '-'){ 
      num1 = curr_num; 
      num2 = 0; 
      curr_num = 0; 
      for(j = i + 1; j <len; j ++){ 
       if(!isdigit(str[j])){ 
        break; 
       } 
       num2 = num2 * 10 + str[j] - '0'; 
      } 
      i = j; 
      if(num1 <= num2){ 
       for(j = num1; j <=num2; j++){ 
        AppendIntToStr(str_to_out,j); 
        outlen = strlen(str_to_out); 
        if(j<num2){ 
         str_to_out[outlen] = ','; 
         outlen++; 
        } 
       } 
      } 
      else{ 
       for(j = num2; j <=num1; j++){ 
        AppendIntToStr(str_to_out,j); 
        outlen = strlen(str_to_out); 
        if(j<num1){ 
         str_to_out[outlen] = ','; 
         outlen++; 
        } 
       }    
      } 
      str_to_out[outlen] = str[i]; 
      outlen++; 
      continue; 
     } 
     if(temp_sbl == ',' || temp_sbl == '}'){ 
      AppendIntToStr(str_to_out,curr_num); 
      outlen = strlen(str_to_out); 
      str_to_out[outlen] = temp_sbl; 
      outlen++; 
      curr_num = 0; 
      continue; 
     } 
     curr_num = curr_num * 10 + str[i] - '0'; 

    } 
    strcpy(str,""); 
    RmRedunInt(str_to_out); 
    strcpy(str,str_to_out); 
    return; 
} 

void IntListToStr(char *str, int list[], int length){ 
    int i,j, len = 0; 
    char str_num[50]; 
    str[0] = '{'; 
    len = 1; 
    for(i = 0 ; i < length; i ++){ 
     strcpy(str_num,""); 
     sprintf(str_num,"%d",list[i]); 
     strcat(str,str_num); 
     len = strlen(str); 
     if(i < length - 1) 
      str[len] = ','; 
     else 
      str[len] = '}'; 
     len++; 
    } 
    return; 
} 

int IsExist(int target, int list[], int length){ 
    if(length==0) 
     return 0; 
    int i; 
    for(i=0;i<length;i++) 
     if(list[i]==target) 
      return i+1; 
    return 0; 
} 

void StrToIntList(char *str, int list[], int *count){ 
    int i, j , tempcount = 0, temp_ls[1000], len = strlen(str); 
    int curr_num = 0; 
    for(i = 0 ; i < len ; i ++){ 
     if(str[i] == '{') 
      continue; 
     if(str[i] == ',' || str[i] == '}'){ 
      list[tempcount] = curr_num; 
      tempcount++; 
      curr_num = 0; 
      continue; 
     } 
     curr_num = curr_num * 10 + str[i] - '0'; 
    } 
    *count = tempcount; 
    return; 
} 

void RmRedunInt(char *str_to_out){ 
    int i,j ,len; 
    int ls_num[1000],count = 0, temp_ls[1000], tempcount = 0; 
    char str_temp[MAXL]; 
    strcpy(str_temp,""); 
    StrToIntList(str_to_out,temp_ls,&tempcount); 
    for(i = 0; i < tempcount; i ++){ 
     if(IsExist(temp_ls[i],ls_num,count)) 
      continue; 
     ls_num[count] = temp_ls[i]; 
     count++; 
    } 
    IntListToStr(str_temp,ls_num,count); 
    strcpy(str_to_out,""); 
    strcpy(str_to_out,str_temp); 
    return; 
} 



void AppendIntToStr(char* str, int num){ 
    char str_num[50]; 
    strcpy(str_num,""); 
    sprintf(str_num,"%d",num); 
    strcat(str,str_num); 
    return; 
} 

回答

0

我观察:

  • 您对MinusPoly呼叫奇怪的是当你经过$$作为参数,但$$是规则的返回值。

  • 您从来没有设置expr规则的返回值。如expr_md '/' expr_hi的规则将需要一些处理,如{$$=$1/$3;}

  • 你也犯了其他规则的这个错误。

我建议你先解决这个问题。至于野牛的“内存管理”:它只是作为C程序运行,并没有自己的内存管理。唯一要注意的是使规则左递归,你做的(否则你可能会用完堆栈)。

+0

谢谢!我发现也许这不是野牛的问题,因为我开始另一个小程序,并将所有这些功能放入其中,而不使用野牛,问题也会发生。看起来当函数“Expand()”终止时,“str_to_out”字符串没有被释放。问题是什么...... – pfc

+0

它被释放,因为它是一个自动变量。不过,我确实看到你永远不会用'\ 0'终止'str_to_out'。你必须这样做,例如在调用AppendIntToStr之前。请注意,自动变量未初始化为零。我还建议你使用调试器来检查发生了什么。 –

+0

我还有一个问题。你说我对MinusPoly的调用是字符串,因为我通过$$作为参数。原因是我曾尝试这个“$$ = MinusPoly($ 1,$ 3)”,但是当我返回时,它报告我不能返回本地指针。有什么方法可以解决它吗?谢谢! – pfc