在JISON中解析单个作品

时间:2019-07-08 19:29:32

标签: javascript jison

在JISON中,是否可以解析单个产品的字符串?例如,此原始解析器根据expressions之类的几种形式定义了主ary

现在,这将返回一个可以解析expressions的函数:

var parser = jison.Parser(bnf);
var str = "A(1-3,5)&B(1,2,3)"
var result = parser.parse(str)   // this works 

但是我还想解析与ary

等单个产品相匹配的字符串
var str = "1-3,5"
var result = parser.ary.parse(str)  /// this does not work

下面是一个示例语法,其中删除了一些Javascript:

%start expressions

/* language grammar */
%%

expressions: e EOF {...}
           ;

assign: ID LPAR ary RPAR 
      ;

predicate: COUNT LPAR elist constraint RPAR { ... }
         ;

e : TN        { $$ = {}; }
  | predicate { $$ = $1; }
  | e '&' e   { $$ = _.merge({},$1,$3); }
  | e '!' e   { $$ = { "$or": [$1,$3]}; }
  | '?' e     { $$ = { "$not": $2 };    }
  | '{' e '}' { $$ = $2;                }
  | assign    { $$ = $1;                }
  ;

/* Seguir desde aca. Esta es la unica expr que sigue jodiendo... */
elist: elist SEMI e { ... }
     | e            { ... }
     ;

constraint:  SEMI comparator val { ... }
    | SEMI val {... }
    ;

ary: val { $$ = [$1]; }
   | ary "," val 
    ;


val: NUMBER            { $$ = +$1;                 }
   | '-' NUMBER        { $$ = - (+$2);             }
   | ID                { $$ = $1;                  }
   | STRING            { $$ = $1;                  }
   | NUMBER '-' NUMBER { $$ = _.range(+$1, +$3+1); }
   | '(' ary ')'       { $$ = $1;                  }
   ;

comparator: '$eq'
          | '$lte'
          | '$gte'
          | '$gt'
          | '$lt' { $$ = $1; }
          ;

1 个答案:

答案 0 :(得分:2)

将此功能添加到由解析器生成器生成的解析器中确实很简单,而无需过多考虑解析器生成器的工作方式。您需要的是一些额外的(伪)终端,每个您要开始解析的非终端一个,每个新终端一个新的生产。

如果您可以将词素注入词法流而不跳过箍,这也有帮助,这对于jison肯定是可能的,因为它允许您插入自己的自定义词法分析器,该词法分析器可以注入终端,然后将调用传递给生成的lexer。 (如果需要使用生成的词法分析器,那么如果您的词法分析器生成器允许启动条件,这仍然非常容易。您只需为每个注入的词位定义一个启动条件,该命令立即发出所需的终端,然后重置为标准的启动条件。为了解析实际的输入。此策略有很多变化,具体取决于您可以使用的接口。

基于上述内容,新语法将类似于:

start: old_start
     | EXPR_TOKEN expr
     | ARY_TOKEN ary
     | ...

然后您只需注入正确的终端,解析器将自动以所需的非终端继续。

对于语法为数据的解析器生成器(如Jison)而言,这种转换可以轻松地自动完成,因此您甚至不需要确定您感兴趣的非终结符。

(注意:这使您可以选择目标非终端产品,而不是目标产品。如果您要针对具有多个产品的非终端产品的单个产品进行定位,则需要将该产品复制到新的开始符号。)