在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; }
;
答案 0 :(得分:2)
将此功能添加到由解析器生成器生成的解析器中确实很简单,而无需过多考虑解析器生成器的工作方式。您需要的是一些额外的(伪)终端,每个您要开始解析的非终端一个,每个新终端一个新的生产。
如果您可以将词素注入词法流而不跳过箍,这也有帮助,这对于jison肯定是可能的,因为它允许您插入自己的自定义词法分析器,该词法分析器可以注入终端,然后将调用传递给生成的lexer。 (如果需要使用生成的词法分析器,那么如果您的词法分析器生成器允许启动条件,这仍然非常容易。您只需为每个注入的词位定义一个启动条件,该命令立即发出所需的终端,然后重置为标准的启动条件。为了解析实际的输入。此策略有很多变化,具体取决于您可以使用的接口。
基于上述内容,新语法将类似于:
start: old_start
| EXPR_TOKEN expr
| ARY_TOKEN ary
| ...
然后您只需注入正确的终端,解析器将自动以所需的非终端继续。
对于语法为数据的解析器生成器(如Jison)而言,这种转换可以轻松地自动完成,因此您甚至不需要确定您感兴趣的非终结符。
(注意:这使您可以选择目标非终端产品,而不是目标产品。如果您要针对具有多个产品的非终端产品的单个产品进行定位,则需要将该产品复制到新的开始符号。)