繁体   English   中英

如何使用Jison生成一个处理语法歧义的解析器?

[英]How can I generate a parser with Jison which deals with grammar ambiguity?

我试图通过JisonChucK语言生成一个JavaScript解析器,并且已经有了一个良好的开端,除了生成的解析器无法处理的语言含糊不清。 原始的ChucK编译器是由Bison生成的,并且必须能够以某种方式解决这些歧义。

出于这个问题的目的,我已经将问题简化为解释性语法,其仅呈现出一种模糊性。 作为参考,我已经提出了所有涉及文件的要点 (包括生成的解析器 )。 项目结构如下:

语法本身如下:

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 VarDeclListPrimaryExpression 这使得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)解析器的原因是因为你对TypeDeclPrimaryExpression状态的DeclExpression状态中的LALR(1)解析器不明确。

让我试着解释一下。 如错误消息所述,解析器检测到TypeDeclPrimaryExpression上的冲突。 两者都将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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM