Compiler construction 在使用yacc构建符号表时,如何考虑范围?

Compiler construction 在使用yacc构建符号表时,如何考虑范围?,compiler-construction,yacc,Compiler Construction,Yacc,我的yacc解析器创建了一个符号表,但我需要考虑作用域。我该怎么做?我听说当你退出一个作用域时,符号表会被破坏。仍然不太清楚如何执行此操作。有许多方法可以处理符号表中的作用域。一种非常简单的方法是为每个作用域创建一个单独的表,并维护一个活动作用域列表 无论何时输入新范围,都可以为其创建一个表,并将其添加到活动范围列表的开头。离开作用域时,只需删除活动作用域列表的标题 我通常发现,在解析完作用域后,您不希望破坏表。您以后可能需要它来进行语义分析、生成调试信息等。这是一个问题,正如您似乎已经正确确定

我的yacc解析器创建了一个符号表,但我需要考虑作用域。我该怎么做?我听说当你退出一个作用域时,符号表会被破坏。仍然不太清楚如何执行此操作。

有许多方法可以处理符号表中的作用域。一种非常简单的方法是为每个作用域创建一个单独的表,并维护一个活动作用域列表

无论何时输入新范围,都可以为其创建一个表,并将其添加到活动范围列表的开头。离开作用域时,只需删除活动作用域列表的标题


我通常发现,在解析完作用域后,您不希望破坏表。您以后可能需要它来进行语义分析、生成调试信息等。

这是一个问题,正如您似乎已经正确确定的那样,它只与yacc间接相关。(yacc所做的只是将输入字符串与语法中的字符串进行匹配。)

因此,您可以在代码中执行所有符号管理和所有其他语义处理。您可以使用任何可以想象的数据结构

要组织起来的一些想法:

  • 您可以在输入嵌套范围时创建新的符号表,然后简单地向外执行多个查找,直到找到给定的符号为止

  • 您可以使用一个表,并用其原始词法级别标记每个符号。然后,您需要处理仅在词法级别不同的重复符号,并且需要可以返回多个符号的查找,但您只需要一个表。如果您不打算在退出作用域后保留所有符号,那么这可能比它的价值更麻烦。如果这样做,您可能希望保留一个单独的堆栈,其中包含指向链接的根指针,这些链接将给定范围内的所有符号线程连接在一起


听起来像是符号表的
堆栈
,而不是
列表
右侧,它是范围堆栈。或一个先进先出的范围。或按相关性顺序列出活动范围。我选择后者,因为我会从头到尾遍历列表,找到一个包含我感兴趣的符号的范围。或者一棵树,从边遍历到根。提出的想法在理论上是正确的,但我遇到了一个实现问题:因为yacc是自下而上工作的,所以会遇到符号“before”活动帧是贴花的。因此,在我知道我在“main”中之前,我将看到“int x”。您建议如何解决它?