如果我像这样在 Yacc/Bison 中编写语法文件:
Module
:ModuleName "=" Functions
{ $$ = Builder::concat($1, $2, ","); }
Functions
:Functions Function
{ $$ = Builder::concat($1, $2, ","); }
| Function
{ $$ = $1; }
Function
: DEF ID ARGS BODY
{
/** Lacks module name to do name mangling for the function **/
/** How can I obtain the "parent" node's module name here ?? **/
module_name = ; //????
$$ = Builder::def_function(module_name, $ID, $ARGS, $BODY);
}
这个解析器应该解析如下代码:
main_module:
def funA (a,b,c) { ... }
在我的 AST 中,名称“funA”应重命名为 main_module.funA
。但是当解析器处理 Function
节点时我无法获取模块的信息!
是否有任何 Yacc/Bison 工具可以帮助我处理这个问题,或者我应该改变我的解析风格以避免这种尴尬的情况?
最佳答案
有一个 bison
功能,但如 manual说,小心使用:
$N
withN
zero or negative is allowed for reference to tokens and groupings on the stack before those that match the current rule. This is a very risky practice, and to use it reliably you must be certain of the context in which the rule is applied. Here is a case in which you can use this reliably:
foo: expr bar '+' expr { ... }
| expr bar '-' expr { ... }
;
bar: /* empty */
{ previous_expr = $0; }
;
As long as
bar
is used only in the fashion shown here,$0
always refers to theexpr
which precedesbar
in the definition offoo
.
更干净地说,您可以使用中间规则操作(在模块
中)将模块名称推送到名称堆栈上(这必须是解析上下文的一部分)。然后,您将在规则末尾弹出堆栈。
有关中间规则操作的更多信息和示例,请参阅manual .
关于parsing - 如何解析依赖于父节点信息的子节点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13532818/