You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否为Bison语法规则创建类似宏的列表规则生成机制?

Bison批量生成列表规则的宏机制问题

现有语法示例

当前的Bison语法规则大致如下:

command : 
    TOK_A a_command { $$.obj_a = std::move($2); }
  | TOK_B b_command { $$.obj_b = std::move($2); }
  | TOK_C c_command { $$.obj_c = std::move($2); }
  ....

各子命令的定义示例:

a_command: TOK_A1 a_params1 | TOK_A2 a_params2| ...
b_command: TOK_B1 b_params1 | TOK_B2 b_params2 | ...
c_command: TOK_C1 c_params1 | TOK_C2 c_params2 | ...

需求说明

当前语法只能解析TOK_A TOK_A1 (123)这类单命令行,现在需要支持一行内多个同类型子命令,比如:

TOK_A TOK_A1 (123) TOK_A1 (234) TOK_A1 (356) ...
TOK_A TOK_A2 ("str") TOK_A2 ("str1") TOK_A2 ("st2") ...

当前可行但繁琐的方案

要实现这个需求,可以为每个命令单独定义列表规则,比如:

a_command_list : a_command | a_command_list a_command;
b_command_list : b_command | b_command_list b_command;
c_command_list : c_command | c_command_list c_command;

但每个命令都要写一遍这类规则,重复工作量大。

问题

想知道Bison是否支持类似C宏的机制,比如定义一个模板宏:

#define list_command(cmdName) cmdName##_command_list : cmdName##_command | cmdName##_command_list cmdName##_command;

然后通过list_command(a)这类调用批量生成列表规则,避免重复编写?


解决方案

Bison原生支持m4预处理器,可以用它实现这种批量生成规则的需求,具体步骤如下:

  1. 定义m4宏:在Bison语法文件开头添加m4的宏定义,替代C宏的写法(m4的宏语法和C不同):
define(`list_command', `$1_command_list: $1_command | $1_command_list $1_command;')
  1. 批量生成规则:直接调用宏生成对应命令的列表规则:
list_command(a)
list_command(b)
list_command(c)

这会自动展开为:

a_command_list: a_command | a_command_list a_command;
b_command_list: b_command | b_command_list b_command;
c_command_list: c_command | c_command_list c_command;
  1. 修改主command规则:把原来的单个子命令换成对应的列表规则,并调整动作代码(需要把语义值从单个对象改成容器,比如std::vector):
command : 
    TOK_A a_command_list { $$.obj_a_list = std::move($2); }
  | TOK_B b_command_list { $$.obj_b_list = std::move($2); }
  | TOK_C c_command_list { $$.obj_c_list = std::move($2); }
  ....

注意事项

  • Bison默认启用m4预处理器,除非编译时加了-no-preprocessor参数,所以不需要额外配置就能用。
  • 如果宏里涉及特殊字符(比如|、;),m4会自动处理,不需要额外转义。

内容的提问来源于stack exchange,提问作者Dmitry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 11:21:13