我正在研究关于语法分析的学校主题。目标是创建一种小型语言,以便使用 cairo 库创建矢量图形。我们选择在 C 中使用中间状态。
我们使用 Yacc 生成由 gcc 编译的 C 代码。它工作正常,但我对字符串有一些问题。
这是使用的代码:
int sumChar = 0 ;
char outnb1[20];
char outnb2[20];
sprintf(outnb1, "%f;", $4);
sprintf(outnb2, "%f;", $8);
sumChar = (6+strlen($2)+1+5+strlen($2)+1+strlen(outnb1)+strlen($6)+strlen($7)+strlen(outnb2)+strlen($10)+strlen($11)+1+1+strlen($14)+1);
// $ 14 is the string returned by another part of the code.
printf("String = %s\nSIZE = %d\n",$14,strlen($14));
//The printf here is exact and the string is not truncated :
//cairo_line_to ( cr ,prevPoint[0] ,prevPoint[1]);
//cairo_move_to ( cr ,prevPoint[0] ,prevPoint[1]);
char *result = malloc(sizeof(char)*sumChar);
sprintf(result, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s","\n\nint ",$2,";","\nfor(",$2,"=",outnb1,$6,$7,outnb2,$10,$11,")","{",$14,"}");
printf("String after sprintf = %s\nSIZE = %d\n",$14,strlen($14));
//The printf print something like :
//cairo_line_to ( cr ,prevPoint[0] ,prevPoint[1]);
//cairo_move_to ( cr ,prevPoint[0]�
$$ = result;
我真的不明白为什么字符串在 malloc 之后被截断。这显然是一个内存错误,但我不知道为什么。任何想法或解决方案?
编辑 :
yacc规则:
%union
{
double number;
char * str;
};
%token DRAW <number>NB <str>COMP <str>VARNAME <str>VARFOR <str>INC;
%type <str>D;
%type <str>BLOCFOR;
%type <str>FOR;
FOR : '(' VARFOR '=' NB ';' VARFOR COMP NB ';' VARFOR INC ')' '{' BLOCFOR '}'
{
int sumChar = 0 ;
char outnb1[20];
char outnb2[20];
sprintf(outnb1, "%f;", $4);
sprintf(outnb2, "%f;", $8);
sumChar += (6+strlen($2)+1+5+strlen($2)+1+strlen(outnb1)+strlen($6)+strlen($7)+strlen(outnb2)+strlen($10)+strlen($11)+1+1+strlen($14)+1);
printf("VALUE OF BLOCFOR = %s\nSIZE = %d\n",$14,strlen($14));
char *result = malloc(sizeof(char)*(sumChar+1));
sprintf(result, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s","\n\nint ",$2,";","\nfor(",$2,"=",outnb1,$6,$7,outnb2,$10,$11,")","{",$14,"}");
printf("VALUE OF BLOCFOR AFTER RESULT = %s\nSIZE = %d\n",$14,strlen($14));
printf("%s\n",result );
$$ = result;
}
BLOCFOR : DRAW D '$' {$$ = $2; printf("INSIDE BLOCFOR %s\nSIZE = %d\n",$2,strlen($2));}
我希望它有所帮助。我不能真正给出一个工作代码,因为它需要一个简化的 lex 文件。但是我可以这样说:
char result[sumChar];
result
是正确的,但$$ = result
不起作用(我不能使用 FOR 返回的值,它只是随机字符,如 �G�+0��I�F���I�)
这是 lex 源中 str 值的解析和返回:
<FOR>[[:alpha:]]+ {yylval.str = strdup(yytext);return VARFOR;}
已解决:问题已解决,这是对 sumChar 和 D 令牌内部分配的错误计算。