当前位置: 首页 > 知识库问答 >
问题:

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

林承悦
2023-03-14

我正试图通过Jison为ChucK语言生成JavaScript解析器,并且已经有了一个良好的开端,只是生成的解析器无法处理语言中的歧义。最初的ChucK编译器是由Bison生成的,它必须能够以某种方式解决这些歧义。

出于这个问题的目的,我已经将这个问题简化为一个仅表示一种歧义的解释语法。作为参考,我列出了所有相关文件(包括生成的解析器)的要点。项目结构如下:

  • 语言/词汇。js:lexer

语法本身如下所示:

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);']
    ]
};

模棱两可的是,非终端机DeclExpress可以匹配TypeDecl VarDeclListPrimaryExpress。这使得Jison发出以下警告:

States with conflicts:
State 7
  TypeDecl -> ID . #lookaheads= ID SEMICOLON OP
  PrimaryExpression -> ID . #lookaheads= ID SEMICOLON OP

生成的解析器无法解析测试代码(Type var)=

Error: Parse error on line 1: Unexpected 'SEMICOLON'

据我所知,这是=

那么,我如何生成一个能够处理这种歧义的解析器呢?


共有2个答案

拓拔意
2023-03-14

我发现我可以通过选择“单反”或“lr”(LR1)解析器类型来为这个(简化的)语法生成一个函数解析器:

// Generate SLR parser, since default LALR has conflicts
exports.generate = new Parser(parserConfig, {type: "slr"}).generate;

然而,我仍然想知道为什么默认值(LALR(1))不起作用,因为这应该是Bison生成的。

傅正豪
2023-03-14

你的语法不能与LALR(1)解析器一起使用的原因是,你的语法在TypeDeclPrimaryExpression状态下的DeclExpression状态对LALR(1)解析器不明确。

让我来解释一下。如错误消息所述,解析器在TypeDeclPrimaryExpression上检测到冲突。两者都有ID作为令牌,但由于LALR(1)解析器只能向前看一个令牌,这意味着解析器不知道在解列压缩状态下该做什么。另一方面,单反相机有一种动态的头像,这将以牺牲一些内存来解决冲突。

如果您想让它在LALR(1)解析器上工作,只需将您的DeclExpression规则重构为ID VarDeclList | ID,这样解析器就不必为了找到正确的规则而查看头部。

 类似资料:
  • 我试图用JavaScript为Lilyond音乐符号语言编写一个解析器。我的第一个手册试图工作,但只能处理该语言的一个非常小的子集。由于Lilyond使用bison文件来定义其语法[1],JISON声称能够从bison文件中工作,我的想法是也许可以使用这些定义来生成JavaScript中的解析器。 我在任何地方都找不到这样的例子,试图将这些文件直接输入JISON只会抛出错误。 最好的方法是什么?

  • 根据antlr4书(第159页),并使用语法Ambig. g4,语法歧义可以通过以下方式报告: 或等效代码形式: grun命令使用antlr-4.5.3为我正确报告歧义。但是当我使用代码表单时,我没有收到歧义报告。这是命令跟踪: TestA_Listener.java代码如下: 有人能指出应该如何修改上述java代码以打印歧义报告吗? 为了完整起见,下面是代码 Ambig.g4 : 语法阿姆比格;

  • 这个问题是一个类似问题的后续问题与java代码 - 如何报告语法歧义在antlr4。我正在尝试将该代码移植到c,但是我在使用antlr模板时遇到了一些编译错误。 c中的主程序如下: 我在上面运行了以下命令: 在调用getInterpreter时,我得到了以下编译错误: 你能告诉我如何修复上面的代码吗?我用的是antlr-4.6

  • 问题内容: 我的数据库中有两个表: NEWS表的列: -新闻ID -作者的用户ID) 带有列的USERS表: -用户ID 我要执行此SQL: 当我在PHP中获得结果时,我想获取关联数组并通过获取列名。如何获得具有相同列名的新闻ID和用户ID? 问题答案: 您可以为所选的列设置别名:

  • 在ANTLR4中,我有一个lexer规则,说我可以使用任何字符得到任何单词,但空格和换行符除外。其定义如下: 我还有一个lexer规则(定义在than WORD之前),用于进入EVAL模式: 我考虑的另一个选择是将“word”定义为${and}包围的文本以外的任何东西。但我不知道如何创建这样的lexer规则。 我该怎么解决?要区分评价和词?

  • 我下载了android应用程序的处理文件(这里是链接http://www.gwoptics.org/processing/mobile/BouncingBall/)我尝试在处理时进行编译,但出现以下两个错误: 找不到android.content.res的库 库必须安装在“sketchbook”文件夹中名为“Libraries”的文件夹中。 我想从这个项目生成整个java,这样我就可以使用它的一些