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

基于Peggy实现完整SGF语法解析的递归逻辑问题求助

用Peggy实现SGF递归结构解析的解决方案

核心问题拆解

SGF的递归核心在于GameTree的嵌套(一个GameTree可包含多个子GameTree),以及Value中允许转义括号的字符串规则。你的解析结果为字符数组,本质是规则未返回结构化对象,而是直接返回匹配的字符流。

分步实现规则

下面是完整的Peggy语法规则,每个规则都返回你需要的JSON树形结构:

1. 基础字符与辅助规则

先定义最底层的字符匹配,处理转义逻辑:

// 跳过任意空白符(SGF允许语法元素间加空格、换行等)
_ = [ \t\n\r]*

// 转义字符:匹配\(、\)、\\三种转义情况
EscapedChar = "\\" ( "(" / ")" / "\\" )
// 非括号、非转义的普通字符
NormalChar = [^()\\]
// 合法的Value字符:普通字符或转义字符
ValueChar = NormalChar / EscapedChar

2. 核心结构化规则

Value规则(处理带转义括号的字符串)

Value = value:$(ValueChar+) {
  // 还原转义字符:把\(转为(,\)转为),\\转为\
  return value.replace(/\\(.)/g, "$1");
}

Property规则(属性键值对,如B[aa]、W[bb])

// 属性ID:大写字母开头,可后跟多个大写字母/数字
PropertyID = id:$([A-Z][A-Z0-9]*) { return id; }
// 单个属性:ID后跟1个或多个Value(用[]包裹)
Property = _ id:PropertyID _ "[" _ values:(Value (_ Value)*)? _ "]" _ {
  return { [id]: values ? values.filter(v => v) : [] };
}

Node规则(节点,以;开头,包含多个属性)

Node = _ ";" _ props:(Property*) _ {
  // 合并所有属性到一个data对象
  const data = props.reduce((acc, prop) => ({ ...acc, ...prop }), {});
  return { data, children: [] }; // 初始子节点为空,后续由GameTree填充
}

Sequence规则(连续节点序列)

Sequence = nodes:(Node+) { return nodes; }

GameTree规则(递归核心:括号包裹序列+子GameTree)

GameTree = _ "(" _ seq:Sequence _ children:(GameTree*) _ ")" _ {
  // 生成你需要的Branch结构:包含节点序列和子分支
  return { moves: seq, children: children };
}

Collection规则(顶级结构:多个GameTree)

Collection = trees:(GameTree+) _ { return trees; }

3. 启动解析

将Collection设为起始规则,解析后会返回顶级GameTree数组,每个GameTree包含moves(节点序列)和children(子分支),每个节点有data(属性键值对)和children(子分支挂载入口)。

关键注意事项

  • 递归终止逻辑:Peggy会自动识别闭合括号作为递归终止条件,无需手动控制层级,只要规则定义正确即可。
  • 空白符兼容:所有规则间加入_跳过空白,完全符合SGF允许任意空白的语法规范。
  • 结构化返回:每个规则必须返回对象/数组,而非默认的字符匹配结果,这是从字符数组转为树形结构的核心。

示例解析效果

输入SGF片段:

(;B[aa];W[bb](;B[ac];W[bc])(;B[ca];W[cb]))

解析后生成的JSON结构:

[
  {
    "moves": [
      { "data": { "B": ["aa"] }, "children": [] },
      { "data": { "W": ["bb"] }, "children": [] }
    ],
    "children": [
      {
        "moves": [
          { "data": { "B": ["ac"] }, "children": [] },
          { "data": { "W": ["bc"] }, "children": [] }
        ],
        "children": []
      },
      {
        "moves": [
          { "data": { "B": ["ca"] }, "children": [] },
          { "data": { "W": ["cb"] }, "children": [] }
        ],
        "children": []
      }
    ]
  }
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 22:55:07