Skip to content

topic5: docs - #36

Open
SCOFRD wants to merge 8 commits into
ScratchV-Compiler:mainfrom
SCOFRD:feature/asm_beautifier
Open

topic5: docs#36
SCOFRD wants to merge 8 commits into
ScratchV-Compiler:mainfrom
SCOFRD:feature/asm_beautifier

Conversation

@SCOFRD

@SCOFRD SCOFRD commented Jul 31, 2026

Copy link
Copy Markdown

No description provided.

@github-actions

github-actions Bot commented Jul 31, 2026

Copy link
Copy Markdown

🤖 AI Code Review

共审查 10 个变更文件
⚠️ 另有 1 个文件超过上限(最多 10 个)未审查

📁 benchmarks/bench_asm_beautifier.py

🔴 Potential KeyErrorrun_all_benchmarkssynthetic_1k = benchmarks["synthetic_1k"] 假定字典包含该键,但 diff 未展示 benchmarks 定义。若该键缺失(例如旧代码尚未生成),将引发运行时错误。建议确认 benchmarks 构建中包含 "synthetic_1k" 或加入防御性检查。

🟡 全局 sys.path 修改 — 顶部无条件插入 PROJECT_ROOTsys.path,可能影响其他模块导入顺序或产生冲突。建议将 sys.path 修改移到 if __name__ == "__main__" 块内,或使用 -m 方式运行以确保包路径正确。

🟡 确定性校验可能掩盖问题bench_beautify 中比较每次输出是否一致,虽能发现非确定性行为,但每次循环都进行 result != expected_result 字符串比较(O(n)),对大规模基准测试可能引入额外开销。建议在 repeats > 1 时仅比较前两次结果,或仅在调试模式下启用。

💭 _gen_random_asm 中标签重复定义 — 因 label_{index % 10} 每 15 条指令出现一次,可能多次定义同一标签(如 label_0)。虽然不直接影响基准测试,但生成的汇编可能不合法,影响 beautifier 对标签的处理逻辑。建议使用唯一标签(如 label_{index})或保持原样并注明。

💭 ret 指令硬编码 — 在 opcode == "ret" 分支中直接写 " ret",而非使用 opcode 变量,与其他分支风格不一致。建议统一为 f" {opcode}" 以保持一致性并便于未来扩展。


📁 docs/topic5汇编代码美化器开发文档.md

🔴 设计缺失:段标题与函数标题的幂等性规则未定义
文档第2.2节提到“重复美化不得叠加同名标题或前置空行”,但未说明段标题(如.text.data)如何处理。如果输入已包含段标题注释,美化后是否应保留?还是覆盖?建议明确段标题的幂等性规则,避免重复美化产生过多标题。

🟡 列宽计算逻辑与超长字段处理存在矛盾
第2.2节说“超长字段不截断、不填充,其后字段允许自然右移”,但格式化器又要求“操作码和操作数的最小宽度分别为8和15”。如果字段超长,后续字段自然右移,但后续字段本身可能也需要对齐到统一列?超长字段后,统一对齐列是否会失效?例如操作码超长到20,操作数列起始位置会随之后移,但后续行的操作数是否也应以该行起始位置为准?文档未说明是否所有行对同一字段使用同一最大宽度(经过裁剪),还是仅基于当前行自身的长度。建议指定列宽计算基于所有合法行的 max 值(经过 min 裁剪),而不是逐行独立。

🟡 函数识别规则中使用 call symbol 存在歧义
第2.2节说“识别本文件中直接 call symbol 的目标”。但 call 是伪指令,可能展开为 jal ra, symbol。如果代码中直接使用 jaljalr,是否也识别?建议明确识别范围,或统一处理所有跳转指令(如 jal, jalr, call)。另外,call 也可能出现在注释中?建议明确只识别操作码为 call 的行,避免误判。

🟡 beautify_file() 的原子写入细节未说明清理时机
第2.1节提到“先写入同目录临时文件,成功后原子替换目标”。但未说明失败时是否清理临时文件。第3.3节异常处理中虽提到“输出写入失败时不覆盖原文件,不残留被误认为成功结果的部分文件”,但未提及临时文件的清理。建议补充:失败时删除临时文件,或使用 tempfile.NamedTemporaryFile(delete=True) 结合 shutil.move 实现。

💭 ParseStatusmetadata_label 的语义与异常行不同
metadata_label 被列为 ParseStatus 的一种,但它在异常处理中实际并未归为“异常”,而是“完整保留且不生成函数标题”。文档将其与其他三种异常状态并列(incomplete_operands, unknown_opcode, malformed),但处理方式不同。建议在文档中明确区分:metadata_label 是正常状态,只是特殊处理,不应与异常状态并列在同一表格中(第3.3节表格将三种异常并列,但未包含 metadata_label,这没问题,但第2.2节 ParseStatus 定义中包含了 metadata_label,而第3.3节只列出三种异常,容易混淆)。建议在 ParseStatus 定义处说明 metadata_label 不属于异常状态,其处理见第2.2节。

💭 Alignment 开关与 --no-align 描述不一致
第2.1节 API 参数 align 默认 True,CLI 使用 --no-align 关闭。但文档未明确 --no-align 是否同时禁用函数标题的列对齐(第2.2节说“align=False 时仍插入函数标题,但保持原标签行布局”),这挺好。但 CLI 的 --no-align 描述为“关闭列宽扫描和列对齐”,与函数标题行布局的“保持原标签行布局”一致。建议在 CLI 表格中明确说明函数标题行不受影响,仅影响指令行的对齐。

💭 测试分类中未包含对 metadata_label 的集成测试
第4.1节测试概述中,功能单元测试包含解析测试(覆盖元数据标签),但集成测试未明确列出元数据标签的完整流程(解析+格式化+不生成函数标题)。建议在集成测试中增加用例,验证 _op_/... 标签在完整美化后仍保持原样且不生成标题。

💭 文档中“普通指令”与“伪指令”的注释模板未分开说明
第2.2节提到“指令规格、语义注释模板及 ABI 寄存器映射使用模块级只读常量”,但未给出伪指令的注释模板示例。例如 limv 的注释可能不同,建议至少给出几个典型示例,或说明模板来源(如基于 RISC-V 手册)。


📁 docs/topic5汇编代码美化器设计文档.md

🔴 矛盾:--no-comments 与警告注释 — 2.6 节指出警告注释不受 add_comments 影响,但 2.7 节 --no-comments 仅说“保留用户原始注释”。若用户期望通过 --no-comments 抑制所有自动注释(包括警告),则行为不一致。建议:若 add_comments=False,异常行应输出原始注释(如有),不追加警告;或文档明确说明警告注释不属于“自动注释”范畴,始终输出。

🟡 缺失幂等性测试 — 文档多次强调不重复插入标题和警告,但测试设计中没有明确列出幂等性测试(重复运行美化器输出不变)。建议:在集成测试中增加对同一输入反复运行 beautify_asm 的断言,确保输出稳定。

🟡 性能目标未量化 — 设计目标中“性能可预测”和“对大规模输入保持稳定的处理耗时”没有具体指标。压力测试只记录耗时,但无通过/失败标准。建议:明确最大可接受耗时(如 10MB 文件 < 1s)或性能退化阈值。

💭 未来日期 — 文档版本日期为 2026-08-02,显然是未来时间。建议修正为实际编写日期或使用占位符。


📁 scratchv/backend/asm_beautifier.py

🔴 缺失 INSTRUCTION_SPECS 导致伪指令注释丢失_gen_comment 行 ~132 检查 INSTRUCTION_SPECS.get(base_opcode),若不存在则返回空字符串。但 limvnot 等伪指令的模板存在于 _INST_COMMENTS 中,而 INSTRUCTION_SPECS 可能未包含它们(取决于 asm_parser_for_beautifier)。若如此,这些指令的语义注释将不再生成,退化旧功能。建议:确保 INSTRUCTION_SPECS 覆盖所有已注册模板的指令,或者回退到直接使用模板而绕过 spec 检查。

🟡 label 独占一行改变对齐行为beautify_asm 对齐模式下,对于有标签的指令,先将标签单独输出一行,再另起一行输出指令。而旧版标签与指令在同一行。这改变了输出格式,用户可能预期保持原有布局。建议:提供选项或默认保持标签与指令同行,除非标签过长才换行。

🟡 fence 注释默认值可能不准确_gen_comment 行 ~165 对 fence 硬编码 predecessor = "iorw",但实际 fence 指令的第二个操作数可省略(如 fence 默认 iorw, iorw)。若 INSTRUCTION_SPECSfence 期望两个操作数,则当只有一个操作数时注释错误。建议:根据实际操作数数量动态设置默认值。

💭 _append_section_marker 重复检测使用 strip 可能误判 — 行 ~280 比较 tuple(item.strip() for ...) == marker,但 marker 字符串内部有空格,strip 会去掉两端空格,但 marker 本身无开头/结尾空格,故尚可。但若输出行有尾随空格(如格式化产生的行),strip 后可能匹配失败导致重复插入段标记。建议:使用 rstrip() 或直接比较 item == marker_line

💭 _collect_function_labelscall 目标可能包含非函数符号 — 将 call 的操作数全部加入 call_targets,但 call 也可用于跳转至寄存器,此时操作数不是标签。可能导致误将寄存器名(如 call t0)视为函数。建议:只对操作数看起来像标签(非寄存器)才收集。

💭 _function_marker 格式与旧版不同 — 旧版输出 # --- Function: func_name ---,新版使用 _FUNCTION_MARKER_PREFIX_FUNCTION_MARKER_SUFFIX,但定义了 prefix = "# --- Function: ", suffix = " ---",结果相同。无问题,但确认是保留旧行为。


📁 scratchv/backend/asm_parser_for_beautifier.py

🔴 Bug: metadata_label 状态覆盖_status_for 在 label 是 metadata 时直接返回 "metadata_label",即使 body 非空(即存在指令)。例如 _op_/foo: add a0, a1 会被错误标记为 metadata_label,而非 valid。建议:仅在 body 为空时使用 metadata_label 状态,或修改调用处逻辑。

🟡 冗余逻辑_split_labellabel_is_valid 已包含 not body.startswith(":"),但返回值又重复 and not body.startswith(":")。建议简化。

🟡 建议:非贪婪正则_OPCODE_RE 中操作数匹配使用 (?P<operands>.*?) 配合 $,虽然正确但效率略低。建议改用 (?P<operands>.*) 贪婪匹配。

🟡 建议:函数命名_split_comment 返回结构有效性标志,但函数名未体现。建议重命名为 _split_comment_and_validate 或增加 docstring 说明。

💭 小问题_split_comment 中括号深度检查导致注释内不匹配的括号被标记为 malformed。虽然合理,但可考虑放宽(注释内语法错误通常不影响)。

💭 小问题 — 中文注释与英文注释混用,建议统一为一种语言以保持一致性。

💭 小问题_spec_group 创建的 InstructionSpec 实例被多个 opcode 共享(frozen 安全),但建议添加注释说明共享的含义,避免未来误修改。


📁 tests/test_asm_beautifier.py

🔴 测试文件被完全删除 — 文件 tests/test_asm_beautifier.py 被移除,而 asm_beautifier.py 中的 _parse_line_gen_commentbeautify_asm 等函数仍在生产代码中。删除测试会导致这些关键功能的测试覆盖完全丢失,增加回归风险。建议:确认是否已迁移到其他测试文件;若未迁移,应恢复此文件或添加等效测试。


📁 tests/test_asm_beautifier_blackbox.py

🟡 Lack of timeoutsubprocess.run() in run_cli() has no timeout argument. If the script hangs, the test suite will hang indefinitely.
Suggestion: Add a reasonable timeout, e.g. timeout=10.

🟡 Brittle hardcoded expected strings — Tests like test_cli_abi_register_names_changes_only_comment assert specific comment text ("# ra = sp + gp"). These are implementation details of the beautifier and may change.
Suggestion: Either document these as intentional public output, or match against a pattern (e.g. re.search(r'#\s+\w+')).

💭 Imprecise type hintrun_cli(*args: object) is too loose. Path objects are passed in practice, but object allows any type.
Suggestion: Use *args: str | Path and let str(arg) handle conversion.

💭 Redundant empty-string assertionsassert completed.stderr == "" is fine, but assert not completed.stderr is more idiomatic and avoids the subtle case where stderr is None (though unlikely with text=True).
Suggestion: Use assert not completed.stderr for brevity.


📁 tests/test_asm_beautifier_comments.py

🔴 Potential KeyError in test_all_parser_instructions_have_working_templates — Line 60: _SAMPLE_OPERANDS[role] crashes if INSTRUCTION_SPECS contains an operand role not in _SAMPLE_OPERANDS (e.g., "funct7").
Suggestion: Either verify all roles are covered, or use _SAMPLE_OPERANDS.get(role, "") with a fallback.

🟡 Fragile whitespace assertiontest_abi_aliases_only_change_generated_comment (line 109) asserts "lw x5, 8(x2)" in result. The exact number of spaces depends on beautify_asm alignment logic.
Suggestion: Assert on individual tokens (e.g., "x5" in result and "8(x2)" in result) or use a regex for flexible spacing.

🟡 Exact string equality in test_no_align_only_appends_comment_without_reformatting_code — Line 145: assert result == "add a0,a1,a2 # a0 = a1 + a2" (two spaces before #). This is brittle if the comment spacing logic changes.
Suggestion: Use assert result.endswith("# a0 = a1 + a2") and check that the code part is unchanged.

🟡 test_abi_aliases_do_not_change_non_register_roles (line 130) assumes li x1,x2 generates # ra = x2. This relies on the internal template for li; if li is later expanded or its template changes, the test breaks.
Suggestion: If li is a pseudo-instruction, either test it separately or mock _gen_comment for that opcode, or document the assumption.

💭 test_all_parser_instructions_have_working_templates only tests the minimum operand count for each instruction. Instructions with more operands (e.g., fence with more than min_operands) may have different templates or break.
Suggestion: Add a variant that uses the full operand list (e.g., len(spec.operand_roles)) to ensure templates work for all combinations.

💭 test_empty_opcode_has_no_template_comment (line 82) passes opcode=None to _gen_comment. This is good, but verify that the implementation actually handles None gracefully (e.g., by checking for opcode truthiness). If not, this test could mask a crash.


📁 tests/test_asm_beautifier_formatting.py

🔴 可能的逻辑不一致test_directives_are_preserved.Ldata: .word 4,5 包含标签,但断言该行被原样保留。然而 test_label_comment_is_moved_to_a_separate_aligned_line 显示标签后的注释会被移动到单独行。如果标签移动逻辑对指令行也适用,则此测试会掩盖不一致。建议检查 beautify_asm 是否应统一处理所有标签(无论是否带指令),或明确文档说明规则。

🟡 测试过于依赖具体对齐位置test_short_fields_use_minimum_widths 断言 add_line.index("a0, a1, a2") == 10ret_line.index("#") == add_line.index("#") == 27。这些数字是硬编码的,依赖于列宽算法。如果未来调整列宽(如最小宽度变化),测试会无条件失败,而不是反映行为正确性。建议改用相对断言(如检查所有注释列对齐,或检查操作数起始列一致)而非绝对位置。

🟡 test_no_align 可能过于严格 — 断言 beautify_asm(source, align=False) == source 假设 align=False 时不做任何修改。但 beautify_asm 可能仍会进行标准化(如去除多余空格、统一换行符)。如果内部实现更改,测试可能意外失败。建议明确该模式的行为契约(是否只控制对齐,保留其他修改?),或放宽断言为“不对齐时列对齐不变,但其他部分可调整”。

💭 测试命名可更简洁 — 如 test_two_pass_alignment_normalizes_operands_and_preserves_comment 过长,但功能描述清晰,属于 nit。

💭 缺少边界测试 — 未覆盖空输入、纯注释行、仅指令行、多行标签等场景。虽然不是必须,但增加这些可提高鲁棒性。


📁 tests/test_asm_beautifier_integration.py

🔴 缺失默认参数测试 — 大多数测试显式传 add_comments=False,仅一个测试使用默认值。默认开启注释时,警告与注释的交互、对齐等路径未覆盖。建议增加 add_comments=True 的测试用例。

🔴 缺少 abi_register_names 参数的正反验证 — 仅有一个测试使用 abi_register_names=True,未验证 False 时的行为差异。建议对比测试两种模式。

🟡 硬编码魔数 27 — 多处硬编码注释列宽 27(如 test_incomplete_...、参数化测试中的计算)。若列宽计算逻辑调整,测试需多处同步修改。建议提取为常量或基于扫描结果动态计算。

🟡 边缘输入覆盖不足 — 未测试空字符串、纯空白、仅注释、仅指令等简单输入。建议补充基础边界用例。

🟡 文件操作错误场景不完整 — 仅测试了 os.replace 失败,但未覆盖输入文件不存在、输出目录不可写、权限错误等。建议增加异常路径测试。

🟡 脆弱断言依赖具体列号 — 如 test_standalone_comment_aligns_... 中硬编码了 "main:: #..." 的精确空格数,若对齐规则变化会失败。建议改为断言列索引相等或使用计算值。

💭 test_beautify_file_returns_and_writes_result 断言过具体 — 断言 "# ra = sp + gp" 依赖于寄存器映射的实现细节,若映射改变会导致意外失败,建议弱化为验证注释列存在或格式。

💭 test_all_unsafe_statuses_are_excluded_from_scanned_widths 耦合内部函数 — 直接断言 scan_column_widths 的返回值,若重构内部实现(如返回类型变化)测试需更新。可考虑通过最终输出间接验证。

💭 SECTION_BAR 相关硬编码 — 测试中多处使用 "# CODE SECTION" 等字符串,若 SECTION_BAR 格式调整需同步修改。建议基于常量拼接或使用快照测试。

💭 monkeypatch 依赖模块属性monkeypatch.setattr(asm_beautifier.os, "replace", ...) 假设 asm_beautifier 模块有 os 属性,若导入方式改变会破坏。可考虑直接 patch os.replace 全局。



⚠️ 未审查的文件

  • tests/test_parser_for_beautifier.py

@watney1024
watney1024 self-requested a review August 1, 2026 01:23
@SCOFRD SCOFRD changed the title 对topic5增加了设计与开发文档 topic5: docs Aug 3, 2026
@SCOFRD

SCOFRD commented Aug 10, 2026

Copy link
Copy Markdown
Author

test_asm_beautifier.py的测试已迁移,test_asm_beautifier_comments.py、test_asm_beautifier_formatting.py、test_parser_for_beautifier.py负责单元测试,test_asm_beautifier_integration.py负责集成测试,test_asm_beautifier_blackbox.py负责黑盒测试,bench_asm_beautifier.py负责压力测试

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant