Parsing 如何解析依赖于父节点的子节点';信息?

Parsing 如何解析依赖于父节点的子节点';信息?,parsing,compiler-construction,bison,yacc,Parsing,Compiler Construction,Bison,Yacc,如果我用Yacc/Bison编写语法文件,如下所示: main_module: def funA (a,b,c) { ... } 模块 :ModuleName“=”函数 {$$=Builder::concat($1,$2,“,”);} 功能 :功能 {$$=Builder::concat($1,$2,“,”);} |作用 { $$ = $1; } 作用 :DEF ID ARGS BODY { /**缺少模块名,无法对函数进行名称损坏**/ /**如何在此处获取“父”节点的模块名称**/

如果我用Yacc/Bison编写语法文件,如下所示:

main_module:
    def funA (a,b,c) { ... }
模块
:ModuleName“=”函数
{$$=Builder::concat($1,$2,“,”);}
功能
:功能
{$$=Builder::concat($1,$2,“,”);}
|作用
{ $$ = $1; }
作用
:DEF ID ARGS BODY
{
/**缺少模块名,无法对函数进行名称损坏**/
/**如何在此处获取“父”节点的模块名称**/
模块名称=;/????
$$=Builder::def_函数(模块名称、$ID、$ARGS、$BODY);
}
这个解析器应该像这样解析代码:

main_module:
    def funA (a,b,c) { ... }
在我的AST中,名称“funA”应重命名为
main\u module.funA
。但是当解析器处理
函数
节点时,我无法获取模块的信息


是否有任何Yacc/Bison工具可以帮助我处理此问题,或者我是否应该更改解析方式以避免此类尴尬情况?

有一个
Bison
功能,但如前所述,请小心使用:

$N
N
的值为零或负数时,允许引用堆栈上与当前规则匹配的标记和分组之前的标记和分组。这是一种非常危险的做法,要可靠地使用它,您必须确定应用规则的上下文。以下是一个您可以可靠地使用此功能的案例:

只要
bar
仅以此处所示的方式使用,
$0
总是指
foo
定义中
bar
之前的
expr

更清楚地说,您可以使用mid-rule操作(在
Module
中)将模块名称推送到名称堆栈上(必须是解析上下文的一部分)。然后将在规则末尾弹出堆栈


有关mid规则操作的更多信息和示例,请参阅。

我使用类似的方法将父节点的信息推送到堆栈中。但是Yacc/Bison在到达父母之前解析孩子(LR解析器的正常行为?)。所以我在这里得到了一个相反的顺序,堆栈就变得无用了。@snowmantw,这就是为什么需要使用中间规则操作的原因。中间规则操作在规则到达该点时触发,因此如果将一个放在“=”之后(或者,就这一点而言,放在它的前面),它将在
函数
产品之前执行。请参阅编辑答案中的链接。