PL/0运算符扩充实战:从词法分析到解释器的完整编译链路
简介编译原理课程设计常以PL/0为基座进行功能扩充这套资源正对应这一经典任务。资源面向本科生及开发者围绕运算符和语句扩展展开完整呈现了赋值运算“”与“-”、Pascal风格FOR语句含TO与DOWNTO两种步长方向的实现方案选做部分也完成了“”与“--”运算及一维数组支持而字符类型、实数类型、带参函数等留作扩展思考。资源包内共有文件42个以pl0、cod、cpp、pas、obj等文件类型为主既有PL/0源程序和测试用例也有编译生成的中间代码及可执行程序项目工程文件齐全压缩包仅1.25MB便于快速部署对照学习。在具体实现中资源给出清晰代码结构与注释可帮助理解符号表管理、词法分析扩展和句法分析流程运行PL01.exe即可观察循环语句和自增运算的效果。资源已有1053人浏览学习对于正在完成编译原理课程设计或想深入了解PL/0改造的读者是一份轻量而完整的参考素材。1. 对 PL/0 做运算符扩充为什么这是课程设计里最扎实的改法PL/0 是编译原理课程设计里最常被拿来开刀的底子它小到一两个星期能读完但词法分析、递归下降、中间代码生成、栈式虚拟机四层一样不少。很多人拿到题目第一反应是加 while 循环、加 repeat 语句我建议你别急着动语句——从运算符入手。原因很直接运算符的改动会同时逼你动词法、语法、语义和解释器四条链路任何一个环节漏掉程序就会在答辩现场翻车。本文就用「给 PL/0 添加取模 % 和幂运算 ** 」这件事把整条编译链路完整走一遍顺带讲清楚单目负号和符号表联动。适合手上已有 PL/0 基础代码、想交一份结构完整的课设、又不想把整个语言推倒重写的人。2. 为什么从运算符下手四层结构一次全碰2.1 PL/0 的四层骨架每层到底管什么PL/0 源自 Wirth 的教学设计典型实现代码量不大但结构非常清晰。我习惯把它拆成四块去看对应关系如下层典型函数/模块输入输出和运算符的关系词法分析GETSYM源程序字符流token 序列负责把%、**识别成新符号语法分析BLOCK、EXPRESSION、TERM、FACTORtoken 序列中间代码 符号表产生式决定优先级和结合性语义处理GEN函数语法树节点类 P-Code 指令把运算符映射成MOD、PWR等指令解释执行INTERPRET中间代码运行结果栈式虚拟机实际执行新指令理解这张表是动手的前提。很多同学改 PL/0 只改了词法源程序能编译通过一运行就出问题就是因为中间代码和解释器没有同步改。运算符表面上是词法层的符号实际上每扩充一个四层都要过一遍。我自己的经验是改任何东西之前先在纸上把这四层对应的改动点写出来哪怕只写一行字也比直接打开源码乱找强。有人用 C 重写 PL/0有人用 Java 写换语言不换套路递归下降那几行代码长得都差不多。下面代码我统一用类 C 的风格Java 版只需要把指针访问换成对象引用逻辑完全一致。2.2 三个扩充方向与取舍我为什么选了取模和幂运算PL/0 的运算符扩充方向很多常见的有三档取模%优先级和*、/同级词法只需新增一个符号类型语义层加一条MOD指令改动量最小适合先拿它打通全链路。幂运算**优先级高于所有二元运算符而且是右结合词法上要和*做最长匹配区分语法上要新增一层产生式改动量中等但知识点覆盖最全。复合赋值、-需要动赋值语句语法语义上要生成两条指令先取左值再运算再存储工作量最大而且容易改坏原有赋值逻辑。单目负号不改优先级表但要改FACTOR的产生式坑很多后面单独讲。我推荐取模和幂运算组合。取模帮你建立「运算符扩充四层联动」的直觉幂运算逼你去思考优先级和结合性如何落到递归下降的层次结构里。这两个加在一起答辩时老师问优先级、问结合性、问符号表你都有具体改动可以指给他看。复合赋值适合时间充裕的人锦上添花不建议作为第一条改动。2.3 动手前先建基线改第一行代码前必须做的事改 PL/0 之前先把原始版本编译通过并运行一个最小程序这一步不能跳。常见做法是# 假设原始源文件为 pl0.c用 gcc 编译 gcc -o pl0 pl0.c -lm # 准备最小测试程序 test01.pl0 cat test01.pl0 EOF VAR x; BEGIN x : 2 3 END. EOF # 编译并执行 ./pl0 test01.pl0如果你拿到的 PL/0 代码不是 C 而是 Pascal 或 Java无所谓关键是先让原始版本在你的环境里能跑通。这一步的意义有两个第一确认环境没问题避免把环境问题误判成代码问题第二原始输出是你后面所有改动的对照基准。我每次改完一个功能都会拿原始版本的程序重新跑一遍确保旧功能没有被破坏。这一步虽然不产出任何新功能但能帮你省掉后面至少两个小时的排查时间。3. 词法分析器扩展最长匹配与符号表驱动的运算符识别3.1 用静态表驱动运算符识别别写一长串 else if大多数 PL/0 教学代码的GETSYM函数长这样读一个字符switch 判断是、-、*、/还是、、、每个分支一个case。这个写法在最开始没问题但你要加%、**、的时候else if 会越来越长而且双字符运算符的匹配顺序很容易错。更好的做法是把运算符定义成一张静态表按字符串长度从长到短排列逐个尝试匹配struct op_entry { const char *text; /* 源码中的运算符文本 */ enum symbol sym; /* 对应 token 类型 */ int len; /* 文本长度用于最长匹配 */ }; static struct op_entry ops[] { {**, SYM_POWER, 2}, /* 幂运算必须排在 * 前面 */ {, SYM_PLUS_ASSIGN, 2}, {, SYM_NEQ, 2}, {, SYM_LEQ, 2}, {, SYM_GEQ, 2}, {%, SYM_PERCENT, 1}, {, SYM_PLUS, 1}, {-, SYM_MINUS, 1}, {*, SYM_TIMES, 1}, {/, SYM_SLASH, 1}, {, SYM_EQL, 1}, {, SYM_LSS, 1}, {, SYM_GTR, 1}, /* ( ) , ; . 仍按单字符处理 */ };这里的核心原则是「最长匹配优先」遇到**时如果表里*排在**前面词法分析器会先匹配到单个*然后把下一个*又当成一个独立运算符语法分析直接爆炸。所以表内顺序必须按len从大到小排或者读取后用strncmp暴力遍历并记录最长的那个。匹配逻辑本身不复杂读一个非字母、非数字的字符后遍历这张表逐个strncmp找到第一个匹配的就返回对应 token匹配失败则报「非法字符」。这样做的好处是以后再想加运算符只需要往表里加一行不用去改动GETSYM的分支结构。课程设计报告里也能写一块「表驱动词法设计」的内容比干巴巴的 switch 有说服力。3.2 双字符运算符的回退处理匹配失败时必须回退指针双字符运算符还有一个很容易翻车的地方读入两个字符尝试匹配但第二个字符不满足条件。比如源程序里写了* *两个*中间有空格你的词法器先读到一个*然后读到空格这时如果强行匹配**就会失败。处理方式很简单匹配前记录当前字符位置匹配失败就把读取指针回退到起始位置只返回第一个字符对应的 token。代码看起来像这样char c get_char(); for (int i 0; i op_count; i) { if (c ! ops[i].text[0]) continue; /* 尝试匹配完整文本 */ if (strncmp(cur_pos, ops[i].text, ops[i].len) 0) { for (int j 0; j ops[i].len; j) get_char(); /* 消费 */ return ops[i].sym; } } /* 匹配失败回退c 保持当前位置 */ unget_char(c);参数说明get_char()负责从源文件读取下一个字符并维护行列号unget_char()是回退操作把当前字符放回输入流。这里的cur_pos是当前扫描位置的指针用于strncmp。我一般会把行列号也带进 token 结构体里这样调试错误定位信息时能直接知道是第几行第几列出问题。3.3 保留字判断和运算符判断的顺序顺序错了识别全乱PL/0 的GETSYM里有一个经典顺序先跳过空白然后判断是否字母开头——字母开头就连续读取标识符再查保留字表数字开头就连读数字否则进入运算符匹配分支。这个顺序不能颠倒。原因是保留字BEGIN、END、IF、WHILE等在 PL/0 里都是由字母组成的运算符表里没有字母开头的项所以必须先处理标识符分支再处理运算符分支。Java 版本的GETSYM也要保持同样的顺序。如果先查运算符表遇到BEGIN时第一个字符B匹配不上任何运算符会直接报「非法字符」整个程序就废了。这个顺序看起来理所当然但真到了你往表里加**的那一屏代码时很容易手滑把运算符分支挪到前面去。我在给一个同学调试时见过一次他把*的匹配提到了字母判断之前结果所有标识符全部报错搞了半小时才发现是调整代码块顺序时多拖了一行。4. 语法分析、符号表与中间代码联动优先级靠层次而不是靠表4.1 BNF 怎么改取模进 term 层幂运算单独一层PL/0 原始的表达式产生式大致是expression : term { ( | - ) term } term : factor { ( * | / ) factor } factor : ident | number | ( expression )运算符优先级在递归下降里完全由产生式的层次决定越内层的产生式优先级越高。加取模%只需要把它放进 term 层term : factor { ( * | / | % ) factor }但加幂运算**没有这么简单。数学上幂的优先级高于乘除而且它是右结合的2 ** 3 ** 2等价于2 ** (3 ** 2)。放 term 层会得到左结合放 factor 层又会让优先级低于括号表达式。标准做法是新增一层factor : [ - ] power power : primary [ ** power ] primary : ident | number | ( expression )注意 power 产生式里递归出现在运算符右侧primary [ ** power ]写出来是右递归而右递归天然对应右结合。左结合的运算符如*、在递归下降里用循环while实现右结合用递归实现。这两个套路不能混。单目负号-放在 factor 层最开始的位置表示它可以作用于整个 power-2 ** 2在数学惯例里是-(2 ** 2)也就是-4而不是4。如果你把负号放进 primary 里面就变成(-2) ** 2 4答辩时老师问你-2 ** 2等于几你很难解释清楚。4.2 递归下降函数怎么改term 和 power 的对应实现BNF 改完递归下降函数几乎是逐行翻译。以 term 为例加取模后的实现void term(void) { power(); /* 原来是 factor()现在幂运算优先级更高先调 power */ while (sym SYM_TIMES || sym SYM_SLASH || sym SYM_PERCENT) { enum symbol op sym; power(); /* 注意这里也调用 power() */ if (op SYM_TIMES) gen(MUL); else if (op SYM_SLASH) gen(DIV); else gen(MOD); } }逻辑说明term函数先解析一个power然后循环判断下一个 token 是否为乘、除、取模如果是就继续解析右侧的power并生成对应指令。gen(MOD)生成一条不带操作数的运算指令——栈式虚拟机的设计里运算指令只从栈上取操作数不需要操作数字段。power 函数的实现要注意右结合void power(void) { primary(); /* 左操作数 */ if (sym SYM_POWER) { getsym(); power(); /* 右递归天然右结合 */ gen(PWR); } }这里的「右递归 右结合」是关键点。如果用 while 循环代替递归PWR 指令生成的顺序会变成从左到右计算结果从2 ** (3 ** 2)变成(2 ** 3) ** 2两个结果差的不是一点。我在实验报告里专门画了一张指令序列对比图老师一眼就能看出你确实理解了结合性。4.3 中间代码生成与解释器MOD 指令的执行与除零检查中间代码用类 P-Code 指令集新增的MOD和PWR是栈式运算指令解释器执行时从栈上弹出两个操作数计算后再压回。MOD 指令的典型实现case MOD: { int divisor stack[sp]; /* 右操作数 */ int dividend stack[sp - 1]; /* 左操作数 */ if (divisor 0) { error(mod by zero); halt 1; break; } stack[sp - 1] dividend % divisor; sp--; break; }参数说明栈顶元素stack[sp]是右操作数stack[sp-1]是左操作数。因为栈式指令不携带操作数执行时只能按弹出顺序区分左右。取模操作必须检查除零否则运行时行为取决于 C 的底层实现在 X86 上会直接触发溢出中断表现成程序崩溃或乱码。这里还要注意一个细节PL/0 本身没有负数语法但加了单目负号后(-7) % 4这种表达式是合法的。C 语言里-7 % 4的结果是-3Python 里却是1两种语义不一致这属于未定义行为的灰色地带。我一般会在解释器里强制规定按数学定义取非负余数int r dividend % divisor; if (r 0) r divisor;同时把这个决定写进实验报告的第一页——这是你自己定义语言的语义答辩时有理有据。4.4 符号表与运算符的联动运算符不进符号表但操作数要查表很多人看到「编译原理符号表」相关的热搜以为运算符扩充要往符号表里加记录这是个误解。运算符是词法符号由语法分析器的产生式处理符号表登记的是变量、常量和过程。运算符和符号表的交汇点在于生成中间代码前需要查符号表确认操作数的类型。PL/0 只有一种整型所以查表工作很轻。但如果你想顺便加个浮点运算符号表里每个变量都要多一个 type 字段语法分析器在factor里读到标识符时要查这个字段决定生成LIT还是LITR或者决定是否需要对操作数做隐式转换。课程设计没必要做这么深但你要能说清楚「运算符本身的优先级由产生式层次决定操作数的合法性由符号表决定」这个分工逻辑。我在实际课设里遇到过这种情况有人把取模直接实现成和乘法平级的 token跳过了符号表类型检查结果a % b里如果 a 是浮点变量解释器会把它当整数运算算出完全错误的结果。5. 排除与避坑从词法到解释器的四个翻车点5.1(-3) * 2算出-9单目负号优先级处理错误现象输入BEGIN x : (-3) * 2 END.期望输出-6实际输出-9。原因单目负号的产生式放错了位置。如果写成factor : [ - ] primary那么(-3) * 2会被解析成-(3 * 2)因为-3里的负号作用范围被限制在 primary 层而*在更高层乘法先算负号后作用。这相当于数学里的-(3*2) -6吗并不是-作用于 primary 之后primary 已经结束乘法发生在更外层结果应该是先算3*26再取负-6但你的解析器却把负号直接存成了「生成一条 NEG 指令」并放在乘法之后。如果 NEG 指令生成在乘法之前就变成(-3) * 2 -6如果生成在乘法之后算式实际变成-(3)*2而-(3)*2 -6这两种结果是相同的。真正会变成-9的情况是负号被解析成二元减法让表达式变成0 - 3 * 2或者(0 - 3) * 2后者恰好是-6只有0 - 3 * 2才是-6。检查你自己的实现发现-3 * 2算成-9通常是 NEG 指令被放置在了乘法之前并且作用域错误。解决把负号放在 factor 层的最高位置并生成独立的 NEG 指令不要复用二元减法指令SUBvoid factor(void) { if (sym SYM_MINUS) { getsym(); power(); gen(NEG); /* 对 power 的结果取负 */ } else { power(); } }这样-3 * 2的解析顺序是factor看到负号解析3生成 NEG再回到term层看到*解析2生成 MUL。指令序列变成LIT 3; NEG; LIT 2; MUL结果是(-3)*2 -6。5.27 % 0不报错或者程序崩溃解释器缺少除零检查现象输入x : 7 % 0;编译通过运行时要么直接段错误要么直到程序结束才给出错误结果。原因编译器生成 MOD 指令时没有检查右操作数是否为字面量 0。运行时栈上的值可变很难在编译期静态排查所有情况唯一可靠的做法是在解释器执行到 MOD 指令时对操作数做检查。解决在解释器的 MOD 分支里加显式判断见 4.3 的代码。如果右操作数等于 0打印错误信息并停止解释器不要继续执行后续指令。这里有个细节除零错误的中止要慢于普通错误处理先记录错误行号可以通过当前指令在 code 数组中的位置查回源码行号再停止。5.3 新增**后表达式右边全部解析失败词法表顺序错误现象加上幂运算后原来能正常编译的x : 2 * 3;开始报语法错误错误位置集中在乘号附近。原因词法运算符表里*排在**前面词法分析器遇到**时先匹配到单个*返回两个乘法 token语法分析器读到两个连续的乘法运算符直接报错。解决把**的表项放在*前面确保最长匹配优先。我强烈建议在表结构里显式增加一个len字段并在遍历时记录「当前匹配到的最长项」而不是单纯依赖表排序。因为表排序是静态的容易在后续加新运算符时被破坏动态记录最长匹配则不容易出错。5.4 报错信息乱跳行词法错误的行列号记录延迟现象输入错误表达式x : 2 %% 3;期望报错在第 1 行第 8 列附近实际报错位置指向文件末尾。原因词法分析器匹配到第一个%后继续向后读取字符消费了第二个%然后才调用error()返回错误位置此时行列号已经多前进了一格。更隐蔽的是某些实现里unget_char()只回退了字符指针没有回退行列号。解决在尝试匹配运算符之前就记录当前行列号saved_row、saved_col匹配操作符文本时使用独立的临时指针不要直接推进主扫描位置。匹配成功后再一次性推进主位置和行列号匹配失败则直接恢复记录的saved_row、saved_col。这样错误定位信息永远是准确的。从那以后我每次写词法器都强制把「先记录、再匹配、后推进」写成注释挂在函数开头因为这个坑我已经踩过一次了。6. 用一组测试用例和 trace 开关验证扩充把中间代码当调试窗口6.1 五组必过用例运算符扩充完后我最先跑下面这五组程序。你自己也可以照抄进测试文件测试程序期望结果验证点x : 7 % 4;3取模基本功能x : 2 ** 3 ** 2;512幂运算右结合性x : -3 ** 2;-9单目负号优先级x : 10 % 0;报除零错误运行时检查生效x : (2 3) % 4;1括号与取模层级这五组用例覆盖了取模、右结合幂运算、单目负号、运行时检查和优先级组合全部通过再去深挖更复杂的程序。6.2 给解释器加 trace 开关打印指令序列PL/0 解释器很小加一个 trace 开关用不了十行代码int trace 1; /* 1 打开0 关闭 */ case MUL: { if (trace) printf([%3d] MUL sp%d\n, pc, sp); stack[sp-1] stack[sp-1] * stack[sp]; sp--; break; }trace 打开后解释器每执行一条指令就打印当前指令地址、指令名和栈深度。升级版可以再打印栈顶三个元素的值这样你能直观看到每个运算前后栈的变化。这个调试习惯帮我解决过不少问题中间代码看着对但运行结果不对打开 trace 后一眼就能看出某个时间点压栈的顺序和想象中相反。6.3 手工跑一遍指令序列人肉验证比调试器更直观对于教学编译器没有比手工执行中间代码更可靠的验证方式了。以x : 2 ** 3 ** 2;为例生成的指令序列大致是LIT 2 LIT 3 LIT 2 PWR PWR STO x你拿一张纸从左到右模拟栈LIT 2 压入 2LIT 3 压入 3LIT 2 压入 2第一个 PWR 弹出 3 和 2压入 9第二个 PWR 弹出 2 和 9压入 512STO x 把 512 存入变量 x。整个过程不到半分钟就能确认右结合生成的指令序列是对的。如果指令序列是LIT 2; LIT 3; PWR; LIT 2; PWR结果就是(2**3)**2 64说明语法层把右结合写成了左结合。从那以后我每次做课设第一步就是先加 trace 开关再写新功能哪怕赶时间也强迫自己手动跑一遍关键指令序列。这个习惯救过我至少三次有一次还是一个特别隐蔽的地址回填问题手工模拟指令时才发现跳转目标少了两个字节。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

Spring Boot 2.6.13 + MySQL8 + Flowable 6.8.1 审批流搭建实战指南

Spring Boot 2.6.13 + MySQL8 + Flowable 6.8.1 审批流搭建实战指南

简介:一套Spring Boot 2.6.13、MySQL 8与Flowable 6.8.1整合的工作流应用工程,面向需要快速落地流程审批、任务管理等场景的Java后端开发者,重点解决流程引擎集成、关系型数据持久化与数据库环境搭建三方面痛点,适合作为企业级应用…

2026/10/12 16:50:52 阅读更多 →
Ubuntu Linux 手动分区避坑指南:主分区、逻辑分区与 swap 分配

Ubuntu Linux 手动分区避坑指南:主分区、逻辑分区与 swap 分配

简介:对于需要在Ubuntu系统安装过程中合理规划硬盘分区的初学者与运维人员,这份PDF文档系统梳理了最合理的分区策略。内容涵盖IDE、SCSI、SATA硬盘在Linux中的命名规则,并给出“三个主分区加一个扩展分区”的经典方案,既能有效利用…

2026/10/12 16:50:52 阅读更多 →
Spring Boot @ImportResource 注解:XML 与注解配置混合加载实战

Spring Boot @ImportResource 注解:XML 与注解配置混合加载实战

1. 一个被低估的注解:为什么需要 ImportResource做 Java 后端开发的人,几乎都绕不开 Spring 的注解体系。Component、Service、Configuration、Bean这些注解天天在用,但有一个注解,很多人只在面试题里见过,实际项目里却…

2026/10/12 16:50:51 阅读更多 →

最新新闻

差分约束与SPFA最长路:从糖果题掌握建图与正环判定

差分约束与SPFA最长路:从糖果题掌握建图与正环判定

第一次做 SCOI2011 糖果这道题时,我的第一反应是这题跟“差分约束”有什么关系?n 个小朋友分糖果,无非就是比较大小、算个数,贪心排个序好像就完了。但仔细读题会发现,约束条件不是一串连续的大小关系,而是…

2026/10/12 20:05:20 阅读更多 →
PDT团队KPI指标库深度拆解:三维度19项指标与落地避坑指南

PDT团队KPI指标库深度拆解:三维度19项指标与落地避坑指南

简介:《PDT团队KPI指标库.pdf》是一份面向产品开发团队管理者、项目经理及研发人员的KPI考核体系参考资料,系统梳理了财务、客户、内部业务三大维度共二十余项关键绩效指标,并清晰界定各指标的适用范围与数据来源。资源为单个PDF文件&#xf…

2026/10/12 20:05:20 阅读更多 →
Axure 9负坐标空间全解析:从元件失踪到实战应用

Axure 9负坐标空间全解析:从元件失踪到实战应用

1. 负坐标空间到底是什么?先搞清楚 Axure 9 的画布逻辑做原型设计的人应该都遇到过这么一幕:某天打开一个同事交接的 Axure 9 文件,页面首页空空荡荡,可是右侧大纲面板里明明躺着十几个元件,选中其中一个,画…

2026/10/12 20:05:20 阅读更多 →
IPD开发阶段活动说明:从PDCP到ADCP的36个关键动作与落地指南

IPD开发阶段活动说明:从PDCP到ADCP的36个关键动作与落地指南

简介:这份PDF是一份IPD(集成产品开发)体系中开发阶段活动说明的专用资料,面向产品经理、项目经理、研发管理及职能部门负责人,用于明确项目从开发到验证、发布阶段的关键动作与角色分工。内容围绕外围组成员确定、项目…

2026/10/12 20:05:20 阅读更多 →
豆瓣电影Top250数据分析系统:Python爬虫+pandas+Flask+ECharts全流程实战

豆瓣电影Top250数据分析系统:Python爬虫+pandas+Flask+ECharts全流程实战

简介:本资源为基于Python的豆瓣电影数据分析与可视化系统完整毕业设计包,面向计算机相关专业学生及需要数据分析实战项目的开发者。项目采用Flask搭建后端、ECharts完成图表渲染,结合爬虫采集豆瓣电影数据并用pandas做清洗处理,数…

2026/10/12 20:05:20 阅读更多 →
从生产事故到审查系统:open-code-review如何让代码审查真正落地

从生产事故到审查系统:open-code-review如何让代码审查真正落地

1. 我为什么会在代码审查这件事上栽跟头——项目起点先坦白说,我并不是一开始就想搞什么代码审查工具的。真正让我下决心动手的,是某次上线事故。那是一个数据迁移项目,项目不大,三个人改了差不多两周。代码过了两轮 review&#…

2026/10/12 20:04:19 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →