help-bison
[Top][All Lists]
Advanced

[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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]