如何在Bison中编写递归规则匹配C语言main函数内的多条内容?
问题根源
你写的左/右递归语法规则本身没有逻辑错误,出现仅能匹配单条内容的核心原因是语义动作没有正确拼接所有匹配到的语句节点,归约时仅保留了单侧节点的结果:
- 左递归归约顺序为从左到右,若归约时仅将右值
$2赋值给结果$$,最终只会保留最后一条语句 - 右递归归约顺序为从右到左,若归约时仅将左值
$1赋值给结果$$,最终只会保留第一条语句
解决方案
1. 定义语句链表节点结构
首先在Bison的声明段定义可存储多条语句的链表结构,示例如下:
%union { struct stmt_node* stmt; struct stmt_list* stmt_list; } %type <stmt> function_declare %type <stmt_list> function_declare_rec
其中stmt_list结构体需要包含当前语句节点指针、下一条语句节点指针两个核心字段,同时实现两个工具函数:
create_stmt_list_node(stmt):用单条语句初始化链表append_stmt_node(list, new_stmt):将新语句追加到链表末尾
2. 补充递归规则的语义动作
推荐使用Bison更友好的左递归规则,补充拼接逻辑:
function_declare_rec: function_declare { $$ = create_stmt_list_node($1); } | function_declare_rec function_declare { $$ = append_stmt_node($1, $2); } ;
3. 完善main函数规则与输出逻辑
在main函数的匹配规则中接收完整的语句链表,输出时遍历整个链表的所有节点,依次打印每条语句内容即可输出main内的全部内容:
main_func: INT KWD_MAIN '(' ')' '{' function_declare_rec '}' { print_main_func_header(); // 遍历$6指向的语句链表,逐句打印 traverse_and_print_stmt_list($6); print_main_func_footer(); } ;
内容的提问来源于stack exchange,提问作者Γιάννης Γιαννάκος
相关产品推荐
相关产品推荐

