-1

我正在研究关于语法分析的学校主题。目标是创建一种小型语言,以便使用 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 令牌内部分配的错误计算。

4

1 回答 1

0

该变量sumChar不包含+1终止'\0'字符的额外内容。这很可能最终导致未定义的行为,您的问题可能是其中的症状。要么将其添加到通话中,要么添加sumCharmalloc通话中。

于 2013-04-22T12:37:40.363 回答