-
Notifications
You must be signed in to change notification settings - Fork 0
Help
HPL 解释器错误代码详解与解决方案
HPL 错误码遵循以下格式:
HPL-{类别}-{编号}
| 类别 | 编号范围 | 说明 |
|---|---|---|
| SYNTAX | 1xx | 语法错误 |
| RUNTIME | 2xx | 运行时错误 |
| TYPE | 3xx | 类型错误 |
| IMPORT | 4xx | 导入错误 |
| IO | 5xx | IO 错误 |
错误信息格式:
[ERROR] [HPL-XXXX-XXX] ErrorClass: 错误消息
File: 文件名.hpl
Line: 行号, Column: 列号
Source context:
1 | # 上下文代码
>>> 2 | 错误代码行
3 | # 上下文代码
^
Call stack (most recent first):
1. function_name() at line X
[DOC] 帮助文档: https://github.com/TheSingularityStudio/HPL/wiki/help#HPL-XXXX-XXX
[TIP] 建议: 解决建议
意外的标记
错误信息: Unexpected token
原因:
- 代码中出现了不符合语法规则的标记
- 缺少必要的分隔符(如逗号、冒号)
- 括号不匹配
示例:
# ❌ 错误
main: () => {
echo "Hello" # 缺少右括号
}
# ✅ 正确
main: () => {
echo("Hello")
}解决方案:
- 检查括号是否匹配
- 确认 YAML 语法正确
- 检查冒号和缩进
缺少括号
错误信息: Missing bracket
原因:
- 函数定义或调用时缺少括号
- 代码块的大括号不匹配
示例:
# ❌ 错误
main: () => { # 缺少右大括号
echo "Hello"
call: main()
# ✅ 正确
main: () => {
echo "Hello"
}
call: main()解决方案:
- 检查所有
(是否有对应的) - 检查所有
{是否有对应的} - 使用代码编辑器的括号匹配功能
无效的缩进
错误信息: Invalid indentation
原因:
- YAML 缩进不一致
- 混用空格和制表符
- 缩进层级错误
示例:
# ❌ 错误 - 缩进不一致
main: () => {
echo "Hello" # 2空格
echo "World" # 6空格
}
# ✅ 正确 - 统一使用2空格
main: () => {
echo "Hello"
echo "World"
}解决方案:
- 统一使用 2 个空格缩进
- 不要混用空格和制表符
- 确保同一层级的代码缩进相同
YAML 解析错误
错误信息: YAML parsing error
原因:
- 文件不是有效的 YAML 格式
- 特殊字符未正确转义
- 字符串引号不匹配
示例:
# ❌ 错误 - 字符串包含特殊字符
message = "He said "Hello""
# ✅ 正确 - 使用转义
message = "He said \"Hello\""解决方案:
- 使用 YAML 验证工具检查文件
- 确保字符串使用双引号包围
- 特殊字符使用反斜杠转义
未定义变量
错误信息: Undefined variable
原因:
- 使用了未声明的变量
- 变量名拼写错误
- 变量作用域错误
示例:
# ❌ 错误
main: () => {
echo x # x 未定义
}
# ✅ 正确
main: () => {
x = 10
echo x
}解决方案:
- 检查变量名拼写
- 确保变量在使用前已定义
- 注意变量作用域(局部 vs 全局)
类型不匹配
错误信息: Type mismatch
原因:
- 操作数的类型不兼容
- 函数参数类型错误
示例:
# ❌ 错误 - 字符串和数字相加
result = "10" + 20
# ✅ 正确 - 先转换类型
result = int("10") + 20解决方案:
- 使用
type()函数检查变量类型 - 使用
int()或str()进行类型转换 - 确保操作数类型兼容
索引越界
错误信息: Index out of bounds
原因:
- 数组索引超出有效范围
- 访问空数组的元素
示例:
# ❌ 错误
arr = [1, 2, 3]
echo arr[5] # 索引 5 超出范围(最大为2)
# ✅ 正确
arr = [1, 2, 3]
if (len(arr) > 5) :
echo arr[5]
else :
echo "索引超出范围"解决方案:
- 使用
len()检查数组长度 - 确保索引在
0到len(arr)-1范围内 - 添加边界检查
除零错误
错误信息: Division by zero
原因:
- 除法或取模运算中除数为零
示例:
# ❌ 错误
result = 10 / 0
# ✅ 正确
divisor = 0
if (divisor != 0) :
result = 10 / divisor
else :
echo "错误:除数不能为零"解决方案:
- 添加除零检查
- 使用条件语句验证除数
- 对于可能为零的值,提供默认值
空指针
错误信息: Null pointer
原因:
- 对
null值进行操作 - 访问未初始化对象的属性
示例:
# ❌ 错误
x = null
echo x + 10 # 不能对 null 进行算术运算
# ✅ 正确
x = null
if (x != null) :
echo x + 10
else :
echo "x 为 null"解决方案:
- 使用前先检查是否为
null - 提供默认值
- 确保对象已正确初始化
递归深度超限
错误信息: Recursion depth exceeded
原因:
- 递归调用过深
- 无限递归
示例:
# ❌ 错误 - 无限递归
classes:
BadClass:
badMethod: () => {
this.badMethod() # 无限递归
}
# ✅ 正确 - 有终止条件的递归
classes:
GoodClass:
factorial: (n) => {
if (n <= 1) :
return 1
else :
return n * this.factorial(n - 1)
}解决方案:
- 确保递归有终止条件
- 使用迭代代替深层递归
- 检查递归逻辑
无效的操作
错误信息: Invalid operation for type
原因:
- 对不支持的类型使用操作符
- 类型不兼容的操作
示例:
# ❌ 错误 - 字符串减法
result = "hello" - "world"
# ❌ 错误 - 数组乘法
arr = [1, 2] * 3
# ✅ 正确
# 字符串使用 + 拼接
message = "Hello" + "World"
# 数组使用 + 拼接
arr = [1, 2] + [3, 4]解决方案:
- 查阅操作符支持的数据类型
- 使用正确的操作符
- 必要时进行类型转换
类型转换失败
错误信息: Type conversion failed
原因:
- 无法将值转换为目标类型
- 字符串格式不正确
示例:
# ❌ 错误
x = int("abc") # 无法转换非数字字符串
# ✅ 正确
x = int("123") # 正确转换解决方案:
- 确保字符串格式正确
- 使用
try-catch捕获转换错误 - 验证输入数据
缺少属性
错误信息: Missing property
原因:
- 访问对象不存在的属性
- 属性名拼写错误
示例:
# ❌ 错误
classes:
Person:
init: (name) => {
this.name = name
}
objects:
p: Person("Alice")
main: () => {
echo p.nmae # 拼写错误,应为 name
}解决方案:
- 检查属性名拼写
- 确保属性已定义
- 使用
this.property正确引用
模块未找到
错误信息: Module not found
原因:
- 模块名称拼写错误
- 模块未安装
- 模块路径错误
示例:
# ❌ 错误 - 模块名拼写错误
imports:
- mat # 应为 math
# ✅ 正确
imports:
- math
- io解决方案:
- 检查模块名称拼写
- 确认模块已安装
- 检查模块路径配置
循环导入
错误信息: Circular import
原因:
- 文件 A 导入文件 B,文件 B 又导入文件 A
示例:
# a.hpl
includes:
- b.hpl
# b.hpl
includes:
- a.hpl # 循环导入!解决方案:
- 重构代码,消除循环依赖
- 将公共代码提取到第三个文件
- 使用延迟导入
版本不匹配
错误信息: Version mismatch
原因:
- 模块版本与 HPL 版本不兼容
解决方案:
- 更新 HPL 到最新版本
- 更新模块到兼容版本
- 查看模块的兼容性说明
文件未找到
错误信息: File not found
原因:
- 文件路径错误
- 文件不存在
示例:
imports:
- io
main: () => {
# ❌ 错误 - 文件不存在
content = io.read_file("nonexistent.txt")
# ✅ 正确 - 先检查文件
if (io.file_exists("data.txt")) :
content = io.read_file("data.txt")
else :
echo "文件不存在"
}解决方案:
- 检查文件路径
- 使用
io.file_exists()检查文件 - 使用绝对路径或正确的相对路径
权限拒绝
错误信息: Permission denied
原因:
- 没有文件读取/写入权限
- 文件被其他程序占用
解决方案:
- 检查文件权限
- 以管理员身份运行
- 关闭占用文件的程序
读取错误
错误信息: Read error
原因:
- 文件损坏
- 磁盘错误
- 网络文件不可访问
解决方案:
- 检查文件完整性
- 检查磁盘状态
- 检查网络连接
一般语法错误
说明: 基础语法错误类,未分类的语法问题
解决方案:
- 检查 YAML 语法
- 验证缩进和格式
一般运行时错误
说明: 基础运行时错误类
解决方案:
- 检查变量和对象状态
- 查看调用栈信息
一般类型错误
说明: 基础类型错误类
解决方案:
- 检查操作数类型
- 使用类型转换
一般名称错误
说明: 未定义的名称引用
解决方案:
- 检查变量、函数、类名拼写
- 确保在使用前定义
键错误
说明: 字典中访问不存在的键
示例:
person = {"name": "Alice"}
echo person["age"] # 键 "age" 不存在解决方案:
- 检查键名拼写
- 使用
in操作符检查键是否存在 - 提供默认值
-
阅读错误信息
- 注意错误代码和错误类型
- 查看行号和列号
- 阅读源代码上下文
-
查看调用栈
- 从最近的位置开始排查
- 跟踪函数调用链
- 检查参数传递
-
使用调试输出
main: () => { # 添加调试输出 echo "DEBUG: x = " + x echo "DEBUG: type = " + type(x) # 检查条件 if (x > 5) : echo "DEBUG: condition is true" }
-
简化问题
- 注释掉部分代码
- 创建最小复现示例
- 逐步添加功能
| 错误现象 | 可能原因 | 解决方案 |
|---|---|---|
| 缩进错误 | 空格/制表符混用 | 统一使用2空格 |
| 变量未定义 | 拼写错误或作用域 | 检查拼写和定义位置 |
| 类型错误 | 操作数类型不匹配 | 使用类型转换 |
| 除零错误 | 除数为零 | 添加检查条件 |
| 索引越界 | 数组长度不足 | 检查数组长度 |
| 模块未找到 | 名称拼写错误 | 检查模块名 |
| 文件未找到 | 路径错误 | 检查文件路径 |
提示:遇到错误时,仔细阅读错误信息和源代码上下文,通常能快速定位问题!