我正在学习野牛并遇到问题。我尝试设计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;
}
答案 0 :(得分:0)
我观察:
当您将MinusPoly
作为参数传递时,您对$$
的来电很奇怪,但$$
是该规则的返回值。
您永远不会设置expr
规则的返回值。 expr_md '/' expr_hi
之类的规则需要进行一些处理,例如{$$=$1/$3;}
你也在其他规则中犯了这个错误。
我建议你先解决这个问题。关于&#34;内存管理&#34;野牛:它只是作为一个C程序运行,没有自己的内存管理。唯一需要注意的是使规则保持递归,这样做(否则你可以用完堆栈)。