Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows Bison解析器的执行根据输入文件的大小而终止_Windows_Bison_Filesize_Terminate - Fatal编程技术网

Windows Bison解析器的执行根据输入文件的大小而终止

Windows Bison解析器的执行根据输入文件的大小而终止,windows,bison,filesize,terminate,Windows,Bison,Filesize,Terminate,我使用bison创建了一个解析器,并使用flex创建了一个scanner来解析windows中的setupapi.log文件。我试着通过提取文件的一小部分来执行解析器,它成功了。对于大约20行的文件来说,它工作得很好。但是,当我在正文的最后一行添加了两个字时,它在那里终止了,因为.exe已经停止工作,所以出现了错误 我怎样才能摆脱这个 我在bison文件中使用%union,每当遇到标识符时,都使用flex文件中的malloc分配内存 我的flex文件是: %{ #include <s

我使用bison创建了一个解析器,并使用flex创建了一个scanner来解析windows中的setupapi.log文件。我试着通过提取文件的一小部分来执行解析器,它成功了。对于大约20行的文件来说,它工作得很好。但是,当我在正文的最后一行添加了两个字时,它在那里终止了,因为.exe已经停止工作,所以出现了错误

我怎样才能摆脱这个

我在bison文件中使用%union,每当遇到标识符时,都使用flex文件中的malloc分配内存

我的flex文件是:

%{  
 #include <stdio.h>
#include "check.tab.h"
#include <string.h>
 #include<malloc.h>
int yyline=1;
 int i;

%}



identifier      [_a-zA-Z\.0-9:=&\\{}()\'\-]+
time            ([0-9]+\:[0-9]+\:[0-9]+\.[0-9]+)

%%

"/"         {
            return(SLASH_TOK);
         }

"["         {
            return(OPEN_TOK);
         }

"]"         {
            return(CLOSE_TOK);
         }

">>>"       {
            return (START_TOK); 
        }

"<<<"       {
            return (END_TOK);
         }

"!!!"       {
            return(ERROR_TOK);
         }

  "!"           {
                return(WARN_TOK);
                }

   "...:"       {
                    return(VEND_INFO);
                }

   "bak:"       {
                    return(BAK_TOK);
                }

   "cci:"       {
                    return(CCI_TOK);
                }   



         //SOME MORE TOKENS ARE HERE....


"\n"        {
            yyline++;
        }

{time}      {
           yylval.sval = malloc(strlen(yytext)+1);
           printf("FRM LEXER TIME= %s %s\n",yytext,yylval.sval);
           strncpy(yylval.sval,yytext,strlen(yytext)+1);

            for(i=0;yylval.sval[i]!='\0';i++)
                 {
                        if(!(i<strlen(yytext)))
                        {
                         yylval.sval[i]='\0';
                        }
                }

                printf("FRM LEXER TIME= %s %s\n",yytext,yylval.sval);
                 return(TIME);
        }


[a-zA-Z_0-9:\\]+(\.)+[\.a-zA-Z_0-9:\\]* {printf("REACHED EXTRA\n");return(DATA);}


[a-zA-Z]+(\:)+[\.a-zA-Z_0-9:\\]*    {yylval.sval = malloc(strlen(yytext)+1);
                strncpy(yylval.sval,yytext,strlen(yytext)+1);
                printf("REACHED EXTRA\n");
                 for(i=0;yylval.sval[i]!='\0';i++)
                 {
                        if(!(i<strlen(yytext)))
                        {
                         yylval.sval[i]='\0';
                        }
                }
                return(DATA);
             }

{identifier}    {

                yylval.sval = malloc(strlen(yytext)+1);
                strncpy(yylval.sval,yytext,strlen(yytext)+1);
                //printf("YYTEXT=%s %d\n",yytext,strlen(yytext));

                for(i=0;yylval.sval[i]!='\0';i++)
                {
                        if(!(i<strlen(yytext)))
                        {
                         yylval.sval[i]='\0';
                        }
                }

                printf("FRM LEXER ID = %s %s\n",yytext,yylval.sval);
                return(IDENTIFIER);
             }

%%

int yywrap(void)
{
return 1;
}
%{
#包括
#包括“检查选项卡h”
#包括
#包括
int-yyline=1;
int i;
%}
标识符[\u a-zA-Z\.0-9:=&\\{}()\'\-]+
时间([0-9]+\:[0-9]+\:[0-9]+\.[0-9]+)
%%
"/"         {
返回(SLASH_-TOK);
}
"["         {
返回(打开_-TOK);
}
"]"         {
返回(关闭_-TOK);
}
">>>"       {
返回(启动_-TOK);
}
“来自strcat手册页(也应适用于Windows):

函数的作用是:将src字符串附加到dest字符串, 覆盖dest末尾的空字节('\0'),然后 添加一个终止的空字节。字符串 可能不重叠,并且dest字符串必须有足够的空间用于结果

现在你正在做:

statements : word
     {
            $$=$1;
            printf("STAETEMENT 1\n");
    }

    |statements word    
    {

            $$=$1;
            strcat($$," ");
            strcat($$,$2);
            printf("statements 2\n");
    }
    ;
因此,如果我假设您得到两个单词的输入,则会发生以下情况:

在第一个单词之后,语句指向这个单词,因为您确实使用了
$$=$1
。 然后你的扫描器读取下一个单词,你将一个空格和下一个单词连接到第一个单词。但是你没有注意可用内存。 你正在用C语言编程,这意味着你必须自己做所有的事情

您可以将第二个操作更改为:

statements : statements word
     {
            int lgth1 = strlen($$);
            int lgth2 = strlen($2);
            /* instead of malloc you could also realloc */
            char *tmp = (char *) malloc((lgth1 + lgth2 + 1 + 1) * sizeof(char));
            /* no error handling for clarity */
            sprintf(tmp, "%s %s", $$, $2); /* alternative: strcpy(); strcat(); strcat(); */
            free($$); free($2); /* freeing the memory not used any more */
            $$ = tmp;
    }
这当然不是防弹代码,您还必须修复其他地方。
希望这能有所帮助。

简化程序并给我们一些代码如何?在简化的过程中,注意错误消失的地方。这可能会给你一个问题原因的线索。你的malloc不会为后面的NUL留下空间。使用
snprintf
而不是sprintf。调用两次:第一次使用长度为0的值来获得第二次e需要长度,在malloc'ing足够的存储空间后第二次使用该长度。感谢您指出。我错过了“”实际上,不是\0,但效果是一样的。我认为snprintf()的开销比strlen()大两倍,但优点是不会忘记计算空格字符(或添加任何字符)。我将交替编辑代码,使用常用的非标准GNU/BSD
asprintf
函数,操作将变成
{asprintf(&$$,%s%s',$1,$2);free($1);free($2);}
永不老学:-),并感谢您的第二次更正
statements : statements word
     {
            int lgth1 = strlen($$);
            int lgth2 = strlen($2);
            /* instead of malloc you could also realloc */
            char *tmp = (char *) malloc((lgth1 + lgth2 + 1 + 1) * sizeof(char));
            /* no error handling for clarity */
            sprintf(tmp, "%s %s", $$, $2); /* alternative: strcpy(); strcat(); strcat(); */
            free($$); free($2); /* freeing the memory not used any more */
            $$ = tmp;
    }