gpt4 book ai didi

c - 从中间/底部规则中的最顶层规则获取值

转载 作者:太空宇宙 更新时间:2023-11-03 23:53:39 25 4
gpt4 key购买 nike

我正在做我自己的小语言,我正在尝试创建 block ,但我完全不知道如何跟踪当前 block (因为我需要知道变量是在哪个 block 中创建的)等等等等等等等等)。

我的语法文件看起来像这样(为了简单起见,它不是完整的代码):

%{
struct Node *nodest = NULL;
struct Node *currentblock = NULL;
%}

%start source

%%

source
: stmts { nodest = block($1); currentblock = nodest; }
;

stmts
: stmt
| stmts stmt
;

stmt
: expr_stmt
| iter_stmt
| select_stmt
| comp_stmt
;

expr_stmt
: ';'
| expr ';'
;

expr
: binary_expr
| assign_expr
| call_expr
| decl_expr
| init_expr
| VAR_IDENT
| INTEGER
| '(' expr ')'
;

comp_stmt
: '{' '}'
| '{' stmts '}' { $$ = block($2); currentblock = $$; }
;

decl_expr
: type VAR_IDENT { $$ = declaration($1, $2, currentblock) }
;
/* ... */

type
: TYPE_INT
;

这显然是行不通的,因为 nodest(作为一个包含所有其他节点的 block 节点)实际上在创建 AST 的最后被赋予了一些值,所以它是 NULL其余时间,所以 currentblock 不能像在 decl_expr 中那样使用,因为它当时是 NULL。

所以我的问题是:我怎样才能在代码中获取 nodest 的值(指向它指向的位置或其他)?

或者,如果这真的不可能,你能给我一些说明/提示,告诉我如何才能做到这一点吗?

最佳答案

规则中的操作代码在规则减少时执行,因此如果您希望在流程中更早地执行操作,则需要将它们放在更早减少的规则上。 yacc 和 bison 都允许您引入匿名 epsilon 规则,只需将一个额外的操作放在规则右侧的前面即可。所以你可以这样做:

source: { $$ = currentblock = nodest = empty_block(); } stmts
{ $$ = add_to_block($1, $2); }

comp_stmt:
'{' { $$ = currentblock = empty_block(); } stmts '}'
{ $$ = add_to_block($2, $3); }
;

请注意,当您像这样提前创建 block 时,您必须将它们创建为空(因为您还没有解析任何进入 block 的内容),然后再向它们添加内容。在解析每个 stmt 时将其添加到当前 block 可能更有意义(在这种情况下,您需要确保 currentblock 确实是当前 block 而不是最后一个 block :

source: { currentblock = nodest = empty_block(); } stmts ;

stmts: /* empty*/
| stmts stmt { add_to_block(currentblock, $2; }

comp_stmt:
'{' { $$ = currentblock; currentblock = empty_block(); } stmts '}'
{ $$ = currentblock; currentblock = $2 }
;

关于c - 从中间/底部规则中的最顶层规则获取值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13614939/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com