[英]How can I generate a parser with Jison which deals with grammar ambiguity?
我试图通过Jison为ChucK语言生成一个JavaScript解析器,并且已经有了一个良好的开端,除了生成的解析器无法处理的语言含糊不清。 原始的ChucK编译器是由Bison生成的,并且必须能够以某种方式解决这些歧义。
出于这个问题的目的,我已经将问题简化为解释性语法,其仅呈现出一种模糊性。 作为参考,我已经提出了所有涉及文件的要点 (包括生成的解析器 )。 项目结构如下:
generate
)。 Type var => out;
。 语法本身如下:
grammar = {
Program: [
['ProgramSection', '$$ = new yy.Program($1);']
],
ProgramSection: [
['Expression SEMICOLON', '$$ = new yy.ExpressionStatement($1);']
],
Expression: [
['DeclExpression', '$$ = $1;'],
['Expression OP DeclExpression', '$$ = new yy.ExpFromBinary($1, $2, $3);']
],
DeclExpression: [
['TypeDecl VarDeclList', '$$ = new yy.DeclExp($1, $2, 0);'],
['PrimaryExpression', '$$ = $1;']
],
VarDeclList: [
['VarDecl', '$$ = new yy.VarDeclList($1);']
],
VarDecl: [
['ID', '$$ = new yy.VarDecl($1);']
],
TypeDecl: [
['ID', '$$ = new yy.TypeDecl(new yy.IdList($1), 0);']
],
PrimaryExpression: [
['ID', '$$ = new yy.ExpFromId($1);']
]
};
不明确的是,非终端DeclExpression可以匹配TypeDecl VarDeclList
或PrimaryExpression
。 这使得Jison发出以下警告:
States with conflicts:
State 7
TypeDecl -> ID . #lookaheads= ID SEMICOLON OP
PrimaryExpression -> ID . #lookaheads= ID SEMICOLON OP
并且生成的解析器无法解析测试代码( Type var => out;
),如下所示:
Error: Parse error on line 1: Unexpected 'SEMICOLON'
据我所知,它是=>
运算符之后的部分,解析器尝试匹配规则TypeDecl VarDeclList
。
那么,我如何生成能够处理这种歧义的解析器呢?
你的语法不能使用LALR(1)解析器的原因是因为你对TypeDecl
和PrimaryExpression
状态的DeclExpression
状态中的LALR(1)解析器不明确。
让我试着解释一下。 如错误消息所述,解析器检测到TypeDecl
和PrimaryExpression
上的冲突。 两者都将ID作为标记,但由于LALR(1)解析器只能在前面看一个标记,这意味着解析器在处于DeclExpression
状态时不知道该做什么。 另一方面,SLR具有一种动态的外观,它将以牺牲一些内存为代价来解决冲突。
如果你想让它在LALR(1)解析器上运行,只需将你的DeclExpression
规则重构为ID VarDeclList | ID
ID VarDeclList | ID
,这样解析器就不必为了找到正确的规则而无需查看。
我发现通过选择'slr'(SLR)或'lr'(LR1)解析器类型,我可以为这个(简化的)语法生成一个函数解析器:
// Generate SLR parser, since default LALR has conflicts
exports.generate = new Parser(parserConfig, {type: "slr"}).generate;
我仍然想知道为什么默认(LALR(1))不起作用 ,因为这应该是Bison生成的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.