如何在野牛中管理内存?

时间:2016-10-18 12:04:35

标签: c bison flex-lexer

我正在学习野牛并遇到问题。我尝试设计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)”开始,然后按顺序: “格式()” - > “扩大()”。问题发生在“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;
}

1 个答案:

答案 0 :(得分:0)

我观察:

  • 当您将MinusPoly作为参数传递时,您对$$的来电很奇怪,但$$是该规则的返回值。

  • 您永远不会设置expr规则的返回值。 expr_md '/' expr_hi之类的规则需要进行一些处理,例如{$$=$1/$3;}

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

我建议你先解决这个问题。关于&#34;内存管理&#34;野牛:它只是作为一个C程序运行,没有自己的内存管理。唯一需要注意的是使规则保持递归,这样做(否则你可以用完堆栈)。