[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Setjmp/longjmp makes GLR parser crash
From: |
Colin Daley |
Subject: |
Setjmp/longjmp makes GLR parser crash |
Date: |
Sun, 14 Jul 2013 23:58:19 -0500 |
User-agent: |
Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20130620 Thunderbird/17.0.7 |
Hello All,
I was trying to call a bison/flex GLR parser from an ASP.NET 4.5 web
page by implementing the parser as a DLL. It worked on legal input but
crashed on syntax errors. The reason is the call to longjmp in yyFail.
Fortunately, the call to yyFail() is not very deeply nested, so the use
of longjmp can be avoided without too much difficulty. I propose the
following:
1) static void yyFail (yyGLRStack* yystackp, const char* yymsg)
- remove the noreturn attribute.
- instead of calling longjmp at the end,
/* new global int yylongjmpval */
yylongjmpval = 1;
2) static void yyrecoverSyntaxError(yyGLRStack* yystackp)
- return immediately after every call to yyFail() so that:
/*************/
if (yychar == YYEOF)
yyFail (yystackp, YY_NULL);
becomes
if (yychar == YYEOF){
yyFail (yystackp, YY_NULL);
return;
}
/*************/
if (yyk >= yystackp->yytops.yysize)
yyFail (yystackp, YY_NULL);
becomes
if (yyk >= yystackp->yytops.yysize){
yyFail (yystackp, YY_NULL);
return;
}
/*************/
if (yystackp->yytops.yystates[0] == YY_NULL)
yyFail (yystackp, YY_NULL);
becomes
if (yystackp->yytops.yystates[0] == YY_NULL){
yyFail (yystackp, YY_NULL);
return;
}
3) int yyparse (void)
/*************/
yychar = YYEMPTY;
yylval = yyval_default;
if (! yyinitGLRStack (yystackp, YYINITDEPTH))
goto yyexhaustedlab;
switch (YYSETJMP (yystack.yyexception_buffer))
becomes
yychar = YYEMPTY;
yylval = yyval_default;
yylongjmpval = 0; // new global variable
if (! yyinitGLRStack (yystackp, YYINITDEPTH))
goto yyexhaustedlab;
yysetjmp_start: // label replaces YYSETJMP
switch (yylongjmpval)
/*************/
yyundeleteLastStack (&yystack);
if (yystack.yytops.yysize == 0)
yyFail (&yystack, YY_("syntax error"));
becomes
yyundeleteLastStack (&yystack);
if (yystack.yytops.yysize == 0){
yyFail (&yystack, YY_("syntax error"));
goto yysetjmp_start; // declare new label where YYSETJMP is now
}
/*************/
yyuser_error:
yyrecoverSyntaxError (&yystack);
yyposn = yystack.yytops.yystates[0]->yyposn;
becomes
yyuser_error:
yyrecoverSyntaxError (&yystack);
if (!yylongjmpval)
goto yysetjmp_start;
yyposn = yystack.yytops.yystates[0]->yyposn;
I have implemented these changes and they seem to work.
By the way, I have no idea whether non-GLR parsers are affected or not.
It so happens that the parser that I am working on is a GLR parser.
I am using bison version 2.7.
Regards,
Colin Daley.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Setjmp/longjmp makes GLR parser crash,
Colin Daley <=