0

我使用以下方法生成了一个解析器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;

    }    

以上工作正常如果我给出如下命令:

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

但是如果我输入这样的命令会给出错误:

 project -a abcd    

它抛出一个错误。
同样的方式如果我给出一个命令

project -a -n  

错误:

 Expecting 'TEXT' got `1'  

解决此问题的一种方法是编写所有可能的错误情况,但这将永远不会结束,因为随着命令的增加,可能的错误情况也会增加,无论如何我可以告诉解析器如果它不满足上述任何命令然后抛出一个常见的错误?

提前致谢

4

2 回答 2

1

我猜,projectis PROJECTCOMMAND-ais ADDOPTIONabcdis NAMEOPTION,并且 parser 是第四个节点 - TEXT。您可以选择一个、两个和四个节点,但不是三个。

于 2014-12-10T06:58:22.713 回答
1

这是一个老问题,但我正在回答以防万一有人在这里,这可能会有所帮助。

如果我理解正确,您想要的是能够获得通用错误消息。

我正在做的是围绕.parse()try/catch 子句并将错误消息替换为我想要的错误消息(特别是因为复杂语法中的错误消息可能很大)

但只是为了澄清错误:

问题是没有匹配案例

"PROJECTCOMMAND ADDOPTION TEXT" 
(project -a abcd)

您需要创建此规则。这就是您收到错误的原因。

使用时同样的事情project -a -n你得到的错误是缺少要匹配的参数

"PROJECTCOMMAND ADDOPTION NAMEOPTION TEXT" 

我还将规则重写为:

%%
("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
       }
    ;

通过这种方式,您可以轻松添加不同的选项并一起处理它们的行为。

于 2016-01-20T19:20:45.790 回答