librelist archives

« back to archive

Custom error handling

Custom error handling

From:
Peter Holm
Date:
2011-03-19 @ 15:56
Hello!
I'm writing a Haskell compiler in JavaScript, using Jison to generate my
AST.
To handle certain features in Haskell, I need to be able to define special
behavior when the parser has a parse error. To illustrate what I mean:

In the snippet below (the generated code for error handling), I want to be
able to specify some kind of "try this before we fail", like so:

if (typeof action === 'undefined' || !action.length || !action[0]) {
            //an arbitrary block of code specified by me
            if (!recovering) {

Currently, I am modifying the generated code by hand to provide this
functionality, but a more sound way would be if there was a way to specify
this in the grammar.

I am new to Jison/Bison, and have not found any solution to this in the
documentation. If there is one, help would be greatly appreciated.

Regards,
Peter Holm

Re: [jison] Custom error handling

From:
Zachary Carter
Date:
2011-03-19 @ 17:11
On Sat, Mar 19, 2011 at 11:56 AM, Peter Holm <piotrholmskij@gmail.com> wrote:
> Hello!
> I'm writing a Haskell compiler in JavaScript, using Jison to generate my
> AST.
> To handle certain features in Haskell, I need to be able to define special
> behavior when the parser has a parse error. To illustrate what I mean:
>
> In the snippet below (the generated code for error handling), I want to be
> able to specify some kind of "try this before we fail", like so:
>
> if (typeof action === 'undefined' || !action.length || !action[0]) {
>             //an arbitrary block of code specified by me
>             if (!recovering) {
>
> Currently, I am modifying the generated code by hand to provide this
> functionality, but a more sound way would be if there was a way to specify
> this in the grammar.
>
> I am new to Jison/Bison, and have not found any solution to this in the
> documentation. If there is one, help would be greatly appreciated.

Yes, it is possible to overwrite the parseError function to handle
errors any way you wish. Here's an example[1] from a JavaScript parser
that supreses errors for missing semicolons:

    // Handle parse errors and recover from ASI
    parser.yy.parseError = function (err, hash) {
        // print error except for missing semicolon
        if (!(hash.expected.indexOf("';'") >= 0 && (hash.token ===
'CLOSEBRACE' || parser.yy.lineBreak || parser.yy.lastLineBreak ||
hash.token === 1))) {
            throw new Error(err);
        }
    };

As long as it doesn't throw, the parser can continue.

On the grammar side, you can use error recovery tokens in some cases[2].

[1]: https://github.com/zaach/cafe/blob/master/lib/js.js#L92
[2]: http://dinosaur.compilertools.net/bison/bison_9.html

>
> Regards,
> Peter Holm



-- 
Zach Carter

Re: [jison] Custom error handling

From:
Peter Holm
Date:
2011-04-25 @ 11:38
Hi again!
I'm having problems with the custom error handling in Jison.
I have defined a parseError function:

parser.yy.parseError = function (str, hash) {
        if (!parser.yy.lexer.parseError())
            throw new Error(str);
}

The parseError method in the lexer makes it return a close brace token the
next time lex() is called, and then try to return the erroneous token again.

I.e. the behaviour I want is:
if the parser finds an error,
ignore the erroneous lookahead token,
alert the lexer of the error,
continue parsing the same rule but with a new lookahead token from the
lexer, if one is given else throw an error.

However; instead of that behavior, the parser continues, but throws another
error from here directly afterward:

while (1) {
  if ((TERROR.toString()) in table[state]) {
    break;
  }
  if (state == 0) {
    throw new Error(errStr || "Parsing halted.");
  }
  popStack(1);
  state = stack[stack.length - 1];
}

I reckon there is something I don't quite understand with how jison's error
handling works, but given the way the example in the last reply looks, I
can't see why my approach fails.

Thanks in advance,
//Peter Holm

2011/3/19 Zachary Carter <zack.carter@gmail.com>

> On Sat, Mar 19, 2011 at 11:56 AM, Peter Holm <piotrholmskij@gmail.com>
> wrote:
> > Hello!
> > I'm writing a Haskell compiler in JavaScript, using Jison to generate my
> > AST.
> > To handle certain features in Haskell, I need to be able to define
> special
> > behavior when the parser has a parse error. To illustrate what I mean:
> >
> > In the snippet below (the generated code for error handling), I want to
> be
> > able to specify some kind of "try this before we fail", like so:
> >
> > if (typeof action === 'undefined' || !action.length || !action[0]) {
> >             //an arbitrary block of code specified by me
> >             if (!recovering) {
> >
> > Currently, I am modifying the generated code by hand to provide this
> > functionality, but a more sound way would be if there was a way to
> specify
> > this in the grammar.
> >
> > I am new to Jison/Bison, and have not found any solution to this in the
> > documentation. If there is one, help would be greatly appreciated.
>
> Yes, it is possible to overwrite the parseError function to handle
> errors any way you wish. Here's an example[1] from a JavaScript parser
> that supreses errors for missing semicolons:
>
>    // Handle parse errors and recover from ASI
>    parser.yy.parseError = function (err, hash) {
>        // print error except for missing semicolon
>        if (!(hash.expected.indexOf("';'") >= 0 && (hash.token ===
> 'CLOSEBRACE' || parser.yy.lineBreak || parser.yy.lastLineBreak ||
> hash.token === 1))) {
>            throw new Error(err);
>        }
>    };
>
> As long as it doesn't throw, the parser can continue.
>
> On the grammar side, you can use error recovery tokens in some cases[2].
>
> [1]: https://github.com/zaach/cafe/blob/master/lib/js.js#L92
> [2]: http://dinosaur.compilertools.net/bison/bison_9.html
>
> >
> > Regards,
> > Peter Holm
>
>
>
> --
> Zach Carter
>

Re: [jison] Custom error handling

From:
Zachary Carter
Date:
2011-04-25 @ 13:25
The JavaScript parser I mentioned uses the error token explicitly in
its grammar in places where we want to recover, i.e. in place of a
semicolon:

ExprStatement
    : ExprNoBF ';'
    | ExprNoBF error
    ;

If an error occurs Jison will automatically insert an error token and
if you have grammar rules handle an error token, it can continue. It
will continue with the last token after it recovers from the error, so
no lexer modifications should be needed.

Check out that link on Bison error recovery again:
http://dinosaur.compilertools.net/bison/bison_9.html

On Mon, Apr 25, 2011 at 7:38 AM, Peter Holm <piotrholmskij@gmail.com> wrote:
> Hi again!
> I'm having problems with the custom error handling in Jison.
> I have defined a parseError function:
>
> parser.yy.parseError = function (str, hash) {
>         if (!parser.yy.lexer.parseError())
>             throw new Error(str);
> }
>
> The parseError method in the lexer makes it return a close brace token the
> next time lex() is called, and then try to return the erroneous token again.
>
> I.e. the behaviour I want is:
> if the parser finds an error,
> ignore the erroneous lookahead token,
> alert the lexer of the error,
> continue parsing the same rule but with a new lookahead token from the
> lexer, if one is given else throw an error.
>
> However; instead of that behavior, the parser continues, but throws another
> error from here directly afterward:
>
> while (1) {
>   if ((TERROR.toString()) in table[state]) {
>     break;
>   }
>   if (state == 0) {
>     throw new Error(errStr || "Parsing halted.");
>   }
>   popStack(1);
>   state = stack[stack.length - 1];
> }
>
> I reckon there is something I don't quite understand with how jison's error
> handling works, but given the way the example in the last reply looks, I
> can't see why my approach fails.
>
> Thanks in advance,
> //Peter Holm
>
> 2011/3/19 Zachary Carter <zack.carter@gmail.com>
>>
>> On Sat, Mar 19, 2011 at 11:56 AM, Peter Holm <piotrholmskij@gmail.com>
>> wrote:
>> > Hello!
>> > I'm writing a Haskell compiler in JavaScript, using Jison to generate my
>> > AST.
>> > To handle certain features in Haskell, I need to be able to define
>> > special
>> > behavior when the parser has a parse error. To illustrate what I mean:
>> >
>> > In the snippet below (the generated code for error handling), I want to
>> > be
>> > able to specify some kind of "try this before we fail", like so:
>> >
>> > if (typeof action === 'undefined' || !action.length || !action[0]) {
>> >             //an arbitrary block of code specified by me
>> >             if (!recovering) {
>> >
>> > Currently, I am modifying the generated code by hand to provide this
>> > functionality, but a more sound way would be if there was a way to
>> > specify
>> > this in the grammar.
>> >
>> > I am new to Jison/Bison, and have not found any solution to this in the
>> > documentation. If there is one, help would be greatly appreciated.
>>
>> Yes, it is possible to overwrite the parseError function to handle
>> errors any way you wish. Here's an example[1] from a JavaScript parser
>> that supreses errors for missing semicolons:
>>
>>    // Handle parse errors and recover from ASI
>>    parser.yy.parseError = function (err, hash) {
>>        // print error except for missing semicolon
>>        if (!(hash.expected.indexOf("';'") >= 0 && (hash.token ===
>> 'CLOSEBRACE' || parser.yy.lineBreak || parser.yy.lastLineBreak ||
>> hash.token === 1))) {
>>            throw new Error(err);
>>        }
>>    };
>>
>> As long as it doesn't throw, the parser can continue.
>>
>> On the grammar side, you can use error recovery tokens in some cases[2].
>>
>> [1]: https://github.com/zaach/cafe/blob/master/lib/js.js#L92
>> [2]: http://dinosaur.compilertools.net/bison/bison_9.html
>>
>> >
>> > Regards,
>> > Peter Holm
>>
>>
>>
>> --
>> Zach Carter
>
>



-- 
Zach Carter