Error Handling in JISON

847 views Asked by At

I have generated a parser using JISON:

%lex
%x TEXT
%%

("Project"|"project") {return 'PROJECTCOMMAND';}
"-au" {return 'ADDUSER';}
"-n"  {this.begin('TEXT'); return 'NAMEOPTION';}
"-k" {return 'KEYOPTION';}
"-desc" {return 'DESCRIPTION';}
("--add"|"-a") {return 'ADDOPTION';}
<TEXT>[-a-zA-Z0-9@\.]+ {this.popState(); return 'TEXT';}
<INITIAL,TEXT>\s+ // Ignore white space...

/lex
%%
line    :   
       PROJECTCOMMAND ADDUSER 
            {
                //Project Command of add user
                var res = new Object();
                res.value = "addUser Project";
                return res;
            }      
    |   PROJECTCOMMAND ADDOPTION 
            {
                //Project Command with no arguments
                var res = new Object();
                res.value = "addProject";
                return res;
            }
    |   PROJECTCOMMAND ADDOPTION NAMEOPTION TEXT 
            {
                //Project command with project name as argument
                var res = new Object();
                res.value = "addProject name";
                res.name = $4;
                return res;

    }    

Above works fine If I give commands like:

project -a  
project -au  
project -a -n abc  
...

But gives error If I type in a command like this:

 project -a abcd    

It throws an error.
Same way If I give a command as

project -a -n  

Error:

 Expecting 'TEXT' got `1'  

One way to fix this was to write all possible error cases, but that would be never end because as commands increase possible error cases also increase, Is there anyway I can tell parser that If it does not satisfy any of above commands then throw a common error?

Thanks in Advance

2

There are 2 answers

0
Aleksey Chikin On

I gess, project is PROJECTCOMMAND, -a is ADDOPTION, abcd is NAMEOPTION, and parser is aspected fourth node – TEXT. You have alternatives for one, two and four nodes, but not for three.

0
Lucas Farias On

This is an old question but I'm answering just in case someone get's here and this might help.

If I understood it right what you want is to be able to have a generic error message.

What I'm doing is surrounding the .parse() in a try/catch clause and replacing the error message with the one I want (specially because error messages in a complex grammar can be giant)

But just to clarify the error:

The thing is that there's no match case for

"PROJECTCOMMAND ADDOPTION TEXT" 
(project -a abcd)

You need to create this rule. This is why you get the error.

Same thing when using project -a -n The error you get there is that there's missing an argument to match

"PROJECTCOMMAND ADDOPTION NAMEOPTION TEXT" 

I'd also rewrite the rules to:

%%
("Project"|"project")   return 'PROJECTCOMMAND';

"-au"                   return 'ADDUSER';
"-n"                    return 'NAMEOPTION';
"-k"                    return 'KEYOPTION';
"-desc"                 return 'DESCRIPTION';
("--add"|"-a")          return 'ADDOPTION';
<TEXT>[-a-zA-Z0-9@\.]+ {this.popState(); return 'TEXT';}
<INITIAL,TEXT>\s+
<<EOF>>                 return 'EOF';
/lex
%start line

%%

line
    : PROJECTCOMMAND options EOF
       {
          //enter code here
       }
    | PROJECTCOMMAND options TEXT EOF
       {
          //enter code here
       }
    ;
options
    : option
        {
          //enter code here
        }
    | options option
       {
          //enter code here
       }
    ;

option
    : ADDUSER
        {
          //enter code here
        }
    | NAMEOPTION
       {
          //enter code here
       }
    | KEYOPTION
        {
          //enter code here
        }
    | DESCRIPTION
       {
          //enter code here
       }
    | ADDOPTION
       {
          //enter code here
       }
    ;

This way you can easily add different options and handle their behavior together.