ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

代码转诗之前,先把小语法树做对

代码转诗之前,先把小语法树做对 1024 想做一个轻一点的礼物输入一小段表达式得到十四行中文短诗。这个点子可以交给 AI 扩写但“看起来像解析器”的代码很容易把人带偏。字符串里出现for不代表程序真的有循环数出几个关键词也得不到抽象语法树。我更愿意先做一个很小、能解释的核心。它只接受变量数字加法例如leaf234。输出确实是一棵树却不冒充 JavaScript 编译器。没有函数、注释、负数和括号遇到这些输入就报错而不是猜一个结果。让结构可检查再谈创意10 月 22 日Anthropic 宣布把 Agent Skills 移交给 AAIF。可携带的流程说明让创作工具更容易组合但说明写得完整不等于生成代码实现了它。对这个小玩具而言最便宜的检查就是打印树并数清输出的非空行。下面先扫描词元再按assignment : name number ( number)*解析。加法从左向右结合所以leaf234的右子树是(23)4。解析完成后还要确认没有残余词元避免把leaf23 garbage的前半段当成成功。诗句只使用树里的变量名和数字个数做模板映射。这是确定性文本生成不调用模型不保证押韵也不宣称符合英语商籁体的音步。中文的十四行只是这里选择的一种排版约束。若后面接模型润色应该把原树、模板和润色结果分别保存让读者知道哪里发生了自由改写。为什么宁可少支持一点边界小失败就容易看见。leaf23应通过漏掉等号、加入乘号、把关键词塞进字符串都应拒绝。生产环境若要处理真实 JavaScript需要完整语法解析器与资源限制不该继续往这段玩具代码里堆正则。将代码保存为sonnet.js后运行node sonnet.js。本地验证覆盖结构、非法输入和十四行数量没有运行浏览器界面或真实模型。最后的文字仍需要人读一遍行数是程序能保证的诗意不是。可独立运行的核心例子function parse(source) { if (source.length 200) throw Error(输入过长); const tokens []; const scan /\s*([A-Za-z_][A-Za-z_0-9]*|\d|[])/y; let p 0; while (p source.length) { if (!source.slice(p).trim()) break; scan.lastIndex p; const m scan.exec(source); if (!m) throw Error(不支持的位置 p); tokens.push(m[1]); p scan.lastIndex; } let i 0; const take () tokens[i]; const name take(); if (!/^[A-Za-z_]\w*$/.test(name || ) || take() ! ) throw Error(需要变量表达式); function number() { const t take(); if (!/^\d$/.test(t || )) throw Error(需要非负整数); const value Number(t); if (!Number.isSafeInteger(value)) throw Error(整数超界); return {type:Number, value}; } let value number(); while (tokens[i] ) { take(); value {type:Add, left:value, right:number()}; } if (i ! tokens.length) throw Error(多余词元); return {type:Assign, name, value}; } function countNumbers(node) { if(node.typeNumber) return 1; if(node.typeAdd) return countNumbers(node.left)countNumbers(node.right); if(node.typeAssign) return countNumbers(node.value); throw Error(未知节点); } function poem(tree) { return [ ${tree.name} 是纸上的一枚落叶, 等号替它留下一处位置, ${countNumbers(tree)}个数字靠近尚未惊动夜色, 加号把两盏灯接在一起, 先读左边的枝条, 再看右边的新芽, 树没有许诺整片森林, 只解释这一个句子, 我把能验证的留下, 把不能保证的写在页边, 窗口亮着猫没有回答, 键盘停在下一行之前, 十四行到这里合上, 剩下的空白交给读者 ]; } const tree parse(leaf234); if (tree.value.left.type ! Add || countNumbers(tree)!3 || poem(tree).length ! 14) throw Error(结构测试失败); for (const bad of [x2*3,x2,x 2,x2 garbage]) { let rejectedfalse; try { parse(bad); } catch { rejectedtrue; } if (!rejected) throw Error(应当拒绝bad); } console.log(JSON.stringify(tree)); console.log(poem(tree).join(\n));
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表