仓库源文

https://zhuanlan.zhihu.com/p/2001572382448558748

目标

由此设想,从木兰重现项目的提交历史找到对应提交

相对于原始设想少了函数定义部分,Python代码从一千一下降到约八百行,其中两百行测试代码、一百三的开发辅助代码,算下来实现部分五百行不到,其中分析器部分约两百多。

先试了回退到该提交,在py3.7下可运行如下累积.ul

limit = 4
num = 1
sum = 0
while num <= limit {
    sum = sum + num
    num = num + 1
}

print(sum)

不过第八行为空行则报错如下,需改进反馈可读性:

rply.报错.语法分析报错: (None, SourcePosition(idx=87, lineno=8, colno=1))

去掉空行,运行成功:

% python 中.py 测试/累积.ul
10

另也打算支持中文标识符,额外工作量应该有限。

以此为目标,进行重现。在再画一个鸡蛋的过程中,改进反馈信息、提高rply定制版的易用性等。

第一步

开始考虑先用py3.7之后再支持到3.13,开发流程与前类似,每个小提交包含测试。之前到这个进度约八十个提交,这次希望会略少。

第一步原本按照此进展小结,参照2020年四月十二的提交。但在py3.7.10下运行 python 数.py 报错:AttributeError: 'Num' object has no attribute 'n'。发现ast.Num的属性应为n而非value(估计当年尝试做各种原型时还没注意py版本)。

另考虑到尽量减少额外工作量也方便有兴趣者复现,选择从此项目伊始就直接用当前木兰重现项目支持的Python最高版本3.13。

接下来很快复现了单个数字的解析,但用木兰重现的发布版生成语法树时,发现其无法解析单个数字:

% 木兰 -树 数.ul
 😰 语法错误:文件 "数.ul", 第1行, 第1列, 没认出这个词 "整数"
✋3

于是改第一步目标为输出必需的print,想来也合理。早先还设想过将数学部分作为专用库置于语言之外

代码已开源到:

https://gitee.com/MulanRevive/subset-one

约六十行Python代码,不过调用了木兰重现项目中的语法树格式化功用


草稿

过程

数.ul 4

 😰 语法错误:文件 "数.ul", 第1行, 第1列, 没认出这个词 "整数"
✋4
“/Users/xuanwu/opt/anaconda3/envs/py3_13/lib/python3.13/site-packages/木兰/分析器/语法分析器.py”第1333行:raise 语法错误(
调用层级如下
“/Users/xuanwu/opt/anaconda3/envs/py3_13/lib/python3.13/site-packages/rply/语法分析器.py”第67行:自身.error_handler(state, 预读)
“/Users/xuanwu/opt/anaconda3/envs/py3_13/lib/python3.13/site-packages/木兰/分析器/语法分析器.py”第1382行:节点 = self.分析器.分析(各词, state=self)
“/Users/xuanwu/opt/anaconda3/envs/py3_13/lib/python3.13/site-packages/木兰/中.py”第150行:节点 = 分析器.分析(源码, 源码文件)

修改第一步目标:

print

修改木兰 0.1.9 代码:

from 木兰.功用.调试辅助 import 语法树相关

        print(语法树相关.格式化节点(节点, 1))

报错:

Traceback (most recent call last):
  File "/Users/xuanwu/work/ulang/子集/中.py", line 18, in <module>
    可执行码 = compile(节点, 源码文件, 'exec')
               ~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: required field "lineno" missing from expr

为何木兰重现的语法树里没有args,keywords, type_ignores 是因为空吗?

因为默认用 ast.dump,改用 print(语法树相关.格式化节点(节点, 1)) 之后相同

已中文化标识符,rply的API调用

改为printr后,运行如期报错(py 3.13):

Traceback (most recent call last):
  File "/Users/xuanwu/work/ulang/子集/中.py", line 20, in <module>
    exec(可执行码, {})
    ~~~~^^^^^^^^^^^^^^
  File "输出.ul", line 1, in <module>
    printr
    
NameError: name 'printr' is not defined. Did you mean: 'print'?

目的

加强:

rply 可用性提高