Rebol/Red中load text逆操作:如何从Block还原源文本?
解决Rebol/Red中Block还原为原始源文本的问题
嘿,这个问题我之前折腾过好一阵!你碰到的核心问题其实是form和load的特性导致的:load在解析文本的时候,会把注释、多余的空格换行这些“非语法必要”的信息丢掉,只保留代码的结构;而form只是把Block转成人类可读的字符串,根本没考虑还原语法格式。下面给你分情况说解决方案:
1. 只需要还原等效的语法文本(不需要注释/原始格式)
如果不用管原始的注释、空格布局,只想得到能被重新load的合法代码,别用form,改用mold函数就好——它专门负责生成符合Rebol/Red语法的字符串:
text: { Red [Title: "Red Pretty Printer"] out: none } block: load text ; 用mold替代form restored-text: mold block print restored-text ; 输出: Red [Title: "Red Pretty Printer"] out: none
mold生成的文本可以直接被load重新解析,完全保留代码的逻辑结构,比form靠谱多了。
2. 需要保留注释、原始空格等格式信息
如果你的目标是完全还原包含注释、原始排版的文本,那普通的load就不够用了——因为它已经把注释和空白丢了。这时候得用load/all,它会把所有元素(包括注释、空格、换行)都作为Block的一部分加载进来,之后再用mold/all还原:
拿你给出的示例文本试试:
text: { Red [Title: "Red Pretty Printer"] out: none ; output text spaced: off ; add extra bracket spacing indent: "" ; holds indentation tabs emit-line: func [] [append out newline] emit-space: func [pos] [ append out either newline = last out [indent] [ pick [#" " ""] found? any [ spaced not any [find "[(..."]} ; 用load/all加载所有元素 full-block: load/all text ; 用mold/all还原完整文本 restored-full-text: mold/all full-block print restored-full-text
这样就能得到包含原始注释和格式的文本了,因为load/all没有丢弃那些“无关”的语法元素。
3. 美化代码排版(不是还原原始文本)
如果你其实是想把Block整理成更易读的格式,Red里还有内置的pprint函数,或者你示例里写的那个简易pretty printer也能用:
pprint block ; 自动格式化代码缩进、换行
总结一下:
form是用来做友好展示的,别用来还原代码mold+load:还原无注释的语法等效文本mold/all+load/all:还原包含注释、格式的完整文本pprint:美化代码排版
内容的提问来源于stack exchange,提问作者user310291
相关产品推荐
相关产品推荐

