表达式求值
📅 1.20:¶
发现了表达式求值中的规则部分忽略了!=情况,需要补充,并严格要求gen-expr与expr中的一切rule匹配复合,并重新进行测试
📅 1.21:¶
完成运算情况的完善,对测试程序进行了相应修改,,有一点感想:
1.ai 再好的ai给笨猪用也还是不行,nemu这样的东西前后关联性太大,需要极强的上下文分析思考能力,这个Monica还不够用 2.于是期望两点提升与改进方向: * 自己代码审阅能力的提升:目前太过依赖ai,几乎是ai100%接管工作,明天开始重新复盘,琢磨细节,对pa1的修缮和再理解给出3天时间 * 换用纯血gemini3,试用cursor等,不能再局限于API的使用
📅 1.22:关于 gen-expr 与优化的血泪教训¶
1. 对表达式生成的重新理解
动用随机数(通过取模实现的缩小随机数值,以下简称 choose),来诞生各个数字,并通过 choose 来控制各类运算方式的生成概率。
* 其次是通过生成 C 语言代码,调用 gcc 来实现对生成表达式的计算机求值(标准值)。
* 然后连同标准答案全部输出到一个文件中。
* 由 sdb 中的 cmd_test 读取,再由 expr 计算并对比。
2. 重大挫折与复盘
尝试提升 gen-expr 速度时使用了 gcc -O2,导致了对不合法表达式计算的马虎。
⚠️ 关键教训:在做测试生成器 (Test Generator) 时,千万不要开优化。我们要的就是最原始、最笨拙、最容易崩溃的代码,这样才能帮我们筛选出合法的表达式。 3. 核心感悟 * 关于 Git:妈的幸亏昨天
git commit了一下。敢于重构的底气来自版本控制。 * 关于 C 语言:这种牵一发而动全身的东西,全用 C 语言写成确实厉害。我总觉得日后总有一天我会实现它,这不仅是对自己的自信,更是对浩瀚 C 语言世界的信任。 * 关于系统观:NEMU 应当是个极其精密的机器,每一个齿轮紧紧咬合。我在做的时候急于求成,忽略细节。
再拾起这个东西,就要付出所亏欠的时间和精力,补完对细节的掌控。
📅 1.23:表达式求值再复盘¶
正则表达式的妙用
就是一个把字符转换为可理解运算逻辑的转换器,而这个转换器能较简单地实现这个过程 (如果是手写一个个识别,那么需要写一堆复杂的逻辑判断,还要按照顺序把这些逻辑判断排列好,,, 而正则匹配通过封装的函数与提前定义的运算符类型,把这些逻辑判断集成到一个循环中,相当于把逻辑给集束了,扁平化了) * ai评价:1.集束化:通过规则表来把繁杂的分支逻辑集束 * ai评价:2.扁平化:原本是
if-else分支结构的深层嵌套,在正则表达式作用下变成扁平的循环(一个循环逻辑,通过一个变量不断增实现所有运算逻辑的遍历) * ai评价:3.顺序自动化--->手写方式必须手动排序,正则方式-规则表顺序即优先级 * 正则表达式= (复杂逻辑判断)/(集束化) * 扁平化 * 自动排序 * 洞察:手写方式——命令式——告诉计算机怎么做versus正则方式——声明式——告诉计算机要什么 * 洞察:数据驱动->规则表=数据,处理逻辑-代码<----优势:修改规则不需要改代码逻辑 * 洞察:编译器思想 简图 ✅ 正则表达式的本质 └─ 字符模式的声明式描述
✅ regcomp/regexec 的作用 └─ 预编译 + 快速匹配
✅ 词法分析的流程 └─ 逐字符扫描 + 规则匹配 + 生成token
✅ 设计模式的优势 ├─ 逻辑集束化 ├─ 代码扁平化 └─ 顺序自动化
✅ 与表达式求值的连接 └─ 字符串 → Token → 语法树 → 值 信念的力量——求值的递归逻辑 不多赘述,在代码注释中已经呈现,关键点 :1.火种(点火的那个return),2.燃料(代码中变参的函数调用)