宏系统设计与实现 macro-systems

宏系统设计与实现技能专注于为编程语言开发强大的元编程工具。该技能涵盖卫生宏、过程宏、模式匹配宏的设计与实现,支持准引用、宏展开追踪、错误处理等高级特性。适用于编译器开发、DSL设计、代码生成等场景,帮助开发者构建可扩展、可维护的元编程系统。关键词:宏系统、卫生宏、过程宏、元编程、代码生成、编译器、模式匹配、准引用、宏展开、编程语言设计

架构设计 0 次安装 0 次浏览 更新于 2/25/2026

名称: 宏系统 描述: 用于设计和实现宏系统的专业技能,包括卫生宏、过程宏和宏展开。支持基于模式的宏、准引用和卫生性管理。 允许工具: 读取、写入、编辑、Bash、Glob、Grep

宏系统技能

为编程语言设计和实现宏系统,从简单的基于文本的宏到复杂的卫生宏系统。

能力

  • 设计宏调用语法和模式
  • 实现基于模式的宏匹配和展开
  • 实现带作用域管理的卫生宏展开
  • 处理宏生成标识符的冲突避免
  • 实现带AST操作的过程/语法宏
  • 设计用于代码生成的准引用系统
  • 处理宏调试和错误报告
  • 实现用于开发的宏展开追踪

使用场景

在以下情况时调用此技能:

  • 为新语言设计宏系统
  • 实现卫生宏展开
  • 创建过程宏API
  • 构建准引用设施
  • 调试宏展开问题

输入参数

参数 类型 必填 描述
macroType 字符串 宏系统类型(模式、过程、卫生)
targetLanguage 字符串 宏实现的目标语言(Rust、Scheme等)
syntax 对象 自定义语法规范
hygieneModel 字符串 卫生性模型(作用域集合、标记、无)
features 数组 要实现的特性

特性选项

{
  "features": [
    "模式匹配",
    "准引用",
    "卫生性",
    "过程宏",
    "展开追踪",
    "错误恢复",
    "递归宏",
    "宏模块化"
  ]
}

输出结构

宏系统/
├── 语法/
│   ├── 宏定义.语法     # 宏定义语法
│   ├── 宏调用.语法     # 调用语法
│   └── 准引用.语法     # 准引用语法
├── 展开/
│   ├── 模式匹配器.ts           # 模式匹配引擎
│   ├── 模板替换.ts     # 模板实例化
│   ├── 卫生管理器.ts           # 卫生性/作用域管理
│   └── 展开器.ts                  # 主展开驱动
├── 过程宏/
│   ├── 过程宏-api.ts            # 过程宏API
│   ├── 令牌流.ts              # 令牌操作
│   └── 引用.ts                     # 准引用实现
├── 调试/
│   ├── 展开追踪.ts           # 展开追踪
│   └── 错误报告器.ts            # 宏错误消息
└── 测试/
    ├── 卫生性.测试.ts
    ├── 模式.测试.ts
    └── 展开.测试.ts

宏系统类型

基于模式的宏(Scheme风格)

;; 定义
(define-syntax 我的或
  (syntax-rules ()
    [(我的或) #f]
    [(我的或 e) e]
    [(我的或 e1 e2 ...)
     (let ([t e1])
       (if t t (我的或 e2 ...)))]))

;; 实现模式
interface 宏规则 {
  模式: 模式;
  模板: 模板;
  字面量: string[];
}

function 匹配模式(模式: 模式, 语法: 语法): 绑定 | null {
  // 带省略号处理的模式匹配
}

function 替换模板(模板: 模板, 绑定: 绑定): 语法 {
  // 带卫生性的模板实例化
}

过程宏(Rust风格)

// 派生宏示例
#[proc_macro_derive(Debug)]
pub fn 派生调试(input: TokenStream) -> TokenStream {
    let ast = syn::parse(input).unwrap();
    impl_debug(&ast)
}

// 实现模式
interface 过程宏上下文 {
  输入令牌: 令牌流;
  跨度: 跨度;
  卫生性: 卫生上下文;
}

interface 过程宏 {
  展开(ctx: 过程宏上下文): 令牌流;
}

卫生展开

// 作用域集合卫生性模型(Racket风格)
interface 语法 {
  数据: any;
  作用域: Set<作用域>;
  源位置: 源位置;
}

interface 作用域 {
  id: number;
  绑定: Map<符号, 绑定>;
}

function 引入作用域(语法: 语法, 作用域: 作用域): 语法 {
  return { ...语法, 作用域: new Set([...语法.作用域, 作用域]) };
}

function 切换作用域(语法: 语法, 作用域: 作用域): 语法 {
  const 新作用域 = new Set(语法.作用域);
  if (新作用域.has(作用域)) {
    新作用域.delete(作用域);
  } else {
    新作用域.add(作用域);
  }
  return { ...语法, 作用域: 新作用域 };
}

function 解析(语法: 语法): 绑定 | undefined {
  // 查找具有最大匹配作用域集的绑定
}

准引用实现

// 准引用语法
// `(列表 ,x ,@xs)  =>  (列表 (取消引用 x) (取消引用拼接 xs))

interface 准引用 {
  模板: 准引用模板;
}

type 准引用模板 =
  | { 类型: '字面量'; 值: any }
  | { 类型: '取消引用'; 表达式: 语法 }
  | { 类型: '取消引用拼接'; 表达式: 语法 }
  | { 类型: '列表'; 元素: 准引用模板[] };

function 展开准引用(qq: 准引用, 环境: 环境): 语法 {
  function 展开(模板: 准引用模板): 语法 {
    switch (模板.类型) {
      case '字面量':
        return 引用字面量(模板.值);
      case '取消引用':
        return 求值(模板.表达式, 环境);
      case '取消引用拼接':
        // 拼接到外层列表
        return 求值并拼接(模板.表达式, 环境);
      case '列表':
        return 创建列表(模板.元素.flatMap(展开));
    }
  }
  return 展开(qq.模板);
}

展开追踪

interface 展开步骤 {
  宏名称: string;
  输入语法: 语法;
  输出语法: 语法;
  绑定: Map<string, 语法>;
  位置: 源位置;
}

class 展开追踪器 {
  private 步骤: 展开步骤[] = [];

  记录步骤(步骤: 展开步骤): void {
    this.步骤.push(步骤);
  }

  格式化追踪(): string {
    return this.步骤.map((步骤, i) =>
      `步骤 ${i + 1}: ${步骤.宏名称}
` +
      `  输入: ${格式化语法(步骤.输入语法)}
` +
      `  输出: ${格式化语法(步骤.输出语法)}
` +
      `  绑定: ${格式化绑定(步骤.绑定)}`
    ).join('

');
  }
}

错误处理

interface 宏错误 {
  类型: '模式不匹配' | '卫生性违规' | '展开限制' | '语法错误';
  消息: string;
  宏名称: string;
  输入语法: 语法;
  建议: string[];
}

function 报告宏错误(错误: 宏错误): string {
  const 基础 = `宏展开错误在'${错误.宏名称}'中:
${错误.消息}`;
  const 上下文 = `
输入语法:
  ${格式化语法(错误.输入语法)}`;
  const 提示 = 错误.建议.length > 0
    ? `

建议:
${错误.建议.map(s => `  - ${s}`).join('
')}`
    : '';
  return 基础 + 上下文 + 提示;
}

工作流程

  1. 定义宏语法 - 定义和调用的语法
  2. 实现模式匹配 - 将调用与模式匹配
  3. 构建模板替换 - 用绑定实例化模板
  4. 添加卫生性管理 - 处理标识符作用域
  5. 创建过程API - 用于复杂转换
  6. 构建准引用 - 代码生成助手
  7. 实现追踪 - 用于调试宏展开
  8. 生成测试套件 - 卫生性、模式、边界情况

应用的最佳实践

  • 宏定义与展开的清晰分离
  • 默认卫生性,显式非卫生性逃生舱口
  • 带展开上下文的信息性错误消息
  • 展开深度限制以防止无限递归
  • 通过展开保留源位置
  • 用于IDE支持的增量展开

参考文献

目标流程

  • 宏系统实现.js
  • 解析器开发.js
  • 语义分析.js