【问题标题】:Warning: rule useless in grammar (Bison/Yacc)警告:语法规则无用(Bison/Yacc)
【发布时间】:2020-10-17 06:04:54
【问题描述】:

我一直在尝试解决与当前学校作业相关的这个问题,如果有人能向我解释为什么我会收到来自我的编译器的警告,例如decafast.y:201.13-16: warning: rule useless in grammar [-Wother] | Type.

,我将不胜感激

我在以下两个 pastebin 文件中提供了我的代码:

decafast.lex: https://pastebin.com/2qzG2cwW
decafast.y: https://pastebin.com/Akg5ehW1

我还获得了一个文件“decafast.cc”,其中包含使我能够创建列表的类和方法(我相信这是目的),位于:

https://pastebin.com/M7XRJunL

以及我应该遵循的规范(在页面底部找到的语法):

http://anoopsarkar.github.io/compilers-class/decafspec.html

我主要担心的是为什么我似乎收到了这些(我假设的)导致我的代码失败的警告。我的几乎所有(如果不是全部)语法都被认为是无用的,尽管我在网上搜索(或不理解已经说过的内容),但我仍然没有成功。

如果有人能够启发我,我还有一个次要问题。关于上面的 .cc 文件,我得到了一些实现 decafAST 类的类。在我的解析器生成器文件 (decafast.y) 中,我尝试通过执行以下操作来创建列表

decafStmtList *s = new decafStmtList();

我认为这将允许我使用 push_back() 和 push_front() 方法,这就是为什么我尝试诸如(在 ident_list 的情况下,第 94 行)如果我看到一个 T_ID,然后我创建列出 T_ID(标识符)并将当前 T_ID 推送到列表中。如果我看到 ident_list T_COMMA T_ID 的情况(我认为这是逗号分隔标识符的重复列表的情况),那么我会将其识别为 ident_list 模式,从而将该 T_ID 也推送到列表中.这是使用我提供的列表的正确方法吗?

我想强调的是,由于这是一道作业题,我恳请您提供任何帮助,让我能够按照自己的方式学习。我确信本网站上的用户能够轻松解决此任务,因此我非常感谢您在不给我明确答案的情况下提供的任何见解。谢谢大家的时间!

【问题讨论】:

标签: c++ token bison yacc lex


【解决方案1】:

您提供的语法以:

Program = Externs package identifier "{" FieldDecls MethodDecls "}" .

也就是说,一个程序包括:

  • 可能为空的外部声明列表(使用的库函数)
  • 关键字“包”
  • 标识符
  • 开放式大括号
  • 可能为空的字段声明列表
  • 可能为空的方法声明列表
  • 右大括号。

语法的其余大部分都定义了字段和方法声明的样子,尽管有几个产生式定义了外部声明。

但是您的语法完全不同:(我删除了这些动作,因为它们与语法无关)

start: program
program: extern_list decafpackage
extern_list: 
    | ExternDefn
decafpackage: T_PACKAGE T_ID T_LCB T_RCB

您的decafpackage 仅包含package ID { },大括号之间没有任何内容。

因此,其余大部分语法产生式(详细字段和方法声明)永远无法使用,从而使它们毫无用处。

(另外,您的extern_list 没有定义ExternDecl 的列表。它定义了一个可选的ExternDecl。我认为您在其他列表制作中也犯了同样的错误。)

【讨论】:

  • 我以为 { } 符号是用来表示“0 到 n”的表达式?如果 Externs = { ExternDefn },这是否意味着 Externs(又名 extern_list)将代表 0 个(或更多,最多 n 个)ExternDefn 的列表?感谢您迄今为止的所有帮助。
  • @Solezano:这正是我所说的:“一个可能为空的外部声明列表”。但这不是你的 extern_list 产生的。
  • 我很抱歉没有仔细阅读您的回复。然而,我仍然有一个担忧,它与以下情况有关:在给定的 FieldDecls 定义中:FieldDecls = { FieldDecl },FieldDecl 本身可以是三个语句,其中两个包含一个 { identifier }+, 。这是否意味着我必须创建一个表示 FieldDecl 的列表,该列表将包含一个 FieldDecl 列表和一个将由 FieldDecl“存储”的标识符列表?如果我要制作这些列表,它们必须是 decafAST* 类型(可以访问 .cc 中的 push_back() 方法),但我的令牌包含字符串
  • 再次感谢您抽出宝贵时间向我解释这些概念。我的目标是学习,但是我发现这项任务有些困难,因此我非常感谢您的帮助。
  • 由于在解析标识符列表时没有 vatiabke 类型,因此您需要为该列表创建一些数据类型。所以你需要找出一个合适的类型。有很多可能性,并没有太大区别。也可以使用右递归来修改语法以推迟减少直到类型已知,从而可以将标识符列表的声明脱糖为每个标识符的声明列表。但是你做这个作业迟到了,所以你应该选择最简单的选项......
【解决方案2】:

野牛规则的语法是: 结果:组件……;

据我所知,您的规则都没有分号。

【讨论】:

  • 分号在 bison 和 yacc 中都是可选的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多