吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 702|回复: 11
上一主题 下一主题
收起左侧

[C&C++ 原创] 中文代码解释器(大部分功能完善,稳定性自测)

  [复制链接]
跳转到指定楼层
楼主
abcdefgjh 发表于 2026-1-29 23:10 回帖奖励
# .ch 文件中文解释器

## 项目简介

这是一个使用 C++ 实现的 `.ch` 文件中文解释器,直接解析并执行 `.ch` 后缀文件,无需转换为其他语言。解释器采用类 C++ 的编译解析逻辑,所有关键字均使用中文,支持变量定义、函数定义、基本运算、控制台输出、数组操作、结构体、文件操作和流程控制等核心功能。

**主要特性:**
- ✅ 完整的错误定位系统,所有错误都包含精确的行号信息
- ✅ 智能类型系统:整型运算返回整型,浮点数运算返回浮点数
- ✅ 多维数组支持:支持1-5维数组,最多5维,语法类似C/C++
- ✅ 完整的数组支持:数组定义、初始化、元素访问和赋值
- ✅ 动态数组大小支持:支持使用变量和表达式作为数组大小,语法灵活
- ✅ 文件读写操作:支持文件读取、写入和追加操作
- ✅ 结构体定义和成员访问:支持结构体定义、变量实例化和成员访问
- ✅ 结构体成员赋值:支持直接对结构体成员进行赋值操作
- ✅ 函数重载:支持同名函数不同参数
- ✅ 函数作用域限制:全局作用域只允许变量定义和结构体定义
- ✅ 函数返回类型检查:确保函数返回类型与定义一致
- ✅ 否则如果语句:支持完整的if-else if-else条件判断链
- ✅ ASCII字符兼容:完全支持ASCII码表和中文字符
- ✅ 严格的代码规范:移除所有简化处理,提高代码健壮性
- ✅ 精确错误处理:移除所有"假设"和"默认"处理,提供详细错误信息
- ✅ 系统命令行:支持系统命令行执行功能,类似system()函数
- ✅ 字符类型支持:新增字符型数据类型和字符字面量支持
- ✅ 基础类型转换:提供基础的类型转换功能,包括整数、浮点数、布尔值转换

## 目录结构

```
chplus/
├── main.cpp          # 主程序入口
├── CMakeLists.txt    # CMake构建配置文件
├── README.md         # 项目文档
├── include/          # 头文件目录
│   ├── lexer.h       # 词法分析器头文件
│   ├── parser.h      # 语法分析器头文件
│   └── interpreter.h # 执行器头文件
├── src/              # 源代码目录
│   ├── lexer/        # 词法分析器实现
│   ├── parser/       # 语法分析器实现
│   ├── executor/     # 执行器实现
│   └── utils/        # 工具函数
├── examples/         # 示例文件目录
├── ch_Lib/          # 标准库目录
│   ├── math.ch       # 完整数学库 (100%中文化)
│   ├── string.ch     # 完整字符串库 (100%中文化)
│   ├── file.ch       # 完整文件库 (100%中文化)
│   ├── readme.math.ch.md     # 数学库详细文档
│   ├── readme.string.ch.md   # 字符串库详细文档
│   └── readme.file.ch.md     # 文件库详细文档
└── tests/            # 测试文件目录
```

## 模块化编程与导入功能

.ch解释器支持模块化编程,允许通过导入功能将代码组织成多个文件。

### 导入语法

```ch
导入("ch_Lib/库名.ch");
```

### 标准库概述

.ch解释器提供了三个核心标准库,全部使用中文函数名:

#### 1. 数学库 (math.ch)
完整的C++ cmath功能实现,包含:
- **三角函数**: sin, cos, tan, asin, acos, atan
- **双曲函数**: sinh, cosh, tanh
- **指数对数**: exp, log, log10, sqrt, cbrt
- **取整函数**: ceil, floor, round, trunc
- **绝对值函数**: abs, fabs
- **其他函数**: fmod, gcd, lcm等
- **数学常量**: PI, E, SQRT2等

**使用示例:**
```ch
导入("ch_Lib/math.ch");

定义(空类型) 主函数() {
    定义(小数) radius = 5.0;
    定义(小数) area = PI * radius * radius;
    控制台输出("圆的面积: " + area);  // 输出: 78.539815
}
```

#### 2. 字符串库 (string.ch)
完整的C++ string功能实现,包含:
- **基础操作**: 连接、重复、子串、长度
- **转换功能**: 转大写、转小写、去空白
- **查找功能**: 查找、反向查找、替换
- **验证功能**: 为数字、为字母、为空白
- **字符操作**: 获取字符、翻转、计数
- **高级功能**: 填充、分割、连接
- **类型转换**: 整数转字符串、小数转字符串、布尔值转字符串、字符串转数值
- **内置优化**: 长度、子串、查找等核心函数直接集成在解释器中,性能优化

**使用示例:**
```ch
导入("ch_Lib/string.ch");

定义(空类型) 主函数() {
    定义(字符串) text = "Hello World";
    控制台输出(长度(text));           // 输出: 11
    控制台输出(子串(text, 0, 5));    // 输出: Hello
    控制台输出(查找(text, "World"));  // 输出: 6
    控制台输出(转大写(text));         // 输出: HELLO WORLD
    控制台输出(转小写(text));         // 输出: hello world
   
    // 类型转换示例
    定义(整型) num = 123;
    控制台输出(整数转字符串(num));    // 输出: 123
   
    定义(小数) pi = 3.14159;
    控制台输出(小数转字符串(pi));     // 输出: 3.14
   
    // 高级操作
    定义(字符串) messy = "  hello  ";
    控制台输出(去空白(messy));        // 输出: hello
   
    控制台输出(重复("Hi", 3));        // 输出: HiHiHi
}
```

#### 3. 文件库 (file.ch)
完整的C++文件操作和freopen功能实现,包含:
- **文件重定向**: 类似freopen的流重定向功能
- **文件读写**: 读取、写入、追加文件
- **文件系统**: 检查存在、获取大小、路径操作
- **目录操作**: 创建、删除、重命名
- **文本处理**: 逐行读取、分割、合并
- **临时文件**: 创建临时文件、获取系统目录

**使用示例:**
```ch
导入("ch_Lib/file.ch");

定义(空类型) 主函数() {
    // 文件重定向
    重定向标准输出("log.txt");
    控制台输出("这条信息写入文件");
    恢复标准输出();
   
    // 文件操作
    如果 (文件存在("config.txt")) {
        定义(字符串) content = 读取文件("config.txt");
        控制台输出("配置文件内容: " + content);
    }
}
```

### 循环导入检测

导入功能内置循环导入检测,防止:
- 文件A导入B,B又导入A
- 多层循环导入链
- 嵌套导入循环

**安全特性:**
- 自动检测循环依赖
- 防止无限递归
- 错误提示和回滚机制

### 导入功能使用指南

1. **导入位置**:导入语句通常放在程序开头
2. **相对路径**:支持相对路径和绝对路径
3. **库结构**:建议将库文件放在ch_Lib目录
4. **循环检测**:避免创建循环依赖关系

**最佳实践:**
```ch
// 导入多个库
导入("ch_Lib/math.ch");
导入("ch_Lib/string.ch");
导入("ch_Lib/file.ch");

// 在主函数中使用库功能
定义(空类型) 主函数() {
    // 使用数学库
    定义(小数) result = sin(30) + cos(60);
   
    // 使用字符串库
    定义(字符串) msg = 连接("计算结果: ", 整数转字符串(result));
   
    // 使用文件库
    写入文件("result.txt", msg);
   
    // 使用系统命令行
    系统命令行("echo 系统命令行功能演示");
    系统命令行("dir");
}
```

## 系统命令行功能

.ch解释器支持系统命令行执行功能,类似于C++中的`system()`函数。

### 语法

```ch
系统命令行("要执行的命令");
```

### 功能特性

- **直接执行**:使用系统的shell环境执行命令
- **返回值处理**:获取命令执行的返回码
- **表达式支持**:支持作为表达式使用,返回命令执行结果
- **文件操作集成**:与文件库完美集成,支持文件读取
- **错误报告**:命令执行失败时显示错误信息
- **中文友好**:支持中文路径和中文命令

### 使用示例

```ch
定义(空类型) 主函数() {
    // 传统系统命令行语句(不返回值)
    系统命令行("echo Hello World");
    系统命令行("dir");
   
    // 系统命令行表达式(返回命令执行结果)
    定义(字符串) result = 系统命令行("echo 测试");
    控制台输出("命令结果: " + result);
   
    // 文件操作
    系统命令行("mkdir new_folder");
   
    // 读取文件内容(改进版)
    导入("ch_Lib/file.ch");
    定义(字符串) fileContent = 读取文件("test.txt");
    控制台输出("文件内容: " + fileContent);
}
```

### 实际应用

系统命令行功能特别适合用于:
- **文件管理**:创建、删除、复制、移动文件和目录
- **系统信息**:获取时间、用户信息、系统状态
- **网络操作**:ping、curl、wget等网络工具
- **程序调用**:执行外部程序和脚本
- **自动化任务**:批量处理和系统维护

## 语法说明

### 变量定义

变量定义遵循固定格式:`定义(数据类型) 变量名;`,支持变量初始化和数组定义。

**示例:**
```ch
// 基本类型
定义(整型) a = 10;
定义(字符串) b = "测试内容";
定义(小数) pi = 3.14;
定义(布尔型) isActive = 真;  // 布尔型变量
定义(字符型) ch = 'A';       // 字符型变量
定义(整型) c;

// 数组类型
定义(整型) arr[10];          // 整型数组
定义(字符串) names[5];       // 字符串数组
定义(小数) prices[100];      // 小数数组
定义(布尔型) flags[5];       // 布尔型数组
定义(字符型) chars[26];      // 字符型数组

// 结构体数组(新增功能)
定义(结构体) Point {
    整型 x;
    整型 y;
};
定义(Point) points[10];       // 结构体数组
```

### 函数定义

函数定义规则与变量定义一致,无需额外显式声明「函数」关键字,`定义()`内填写返回值类型(可留空对应无返回值)。

**重要约束:**
- 函数作用域限制:全局作用域(主函数之外)只能定义变量和结构体,不允许执行其他操作(如文件读写、控制台输出等)
- 函数重载:支持同名函数不同参数类型
- 返回类型检查:函数返回类型必须与定义一致

**示例:**
```ch
// 无返回值主函数
定义(空类型) 主函数() {
    控制台输出("Hello World");
}

// 有参数有返回值函数
定义(整型) 求和函数(定义(整型) x, 定义(整型) y) {
    定义(整型) result = x + y;
    返回 result;
}

// 函数重载示例
定义(整型) 计算(定义(整型) a, 定义(整型) b) {
    返回 a + b;
}

定义(小数) 计算(定义(小数) a, 定义(小数) b) {
    返回 a + b;
}

定义(字符串) 计算(定义(字符串) a, 定义(字符串) b) {
    返回 a + b;
}

// 空类型函数示例
定义(空类型) printMessage(定义(字符串) msg) {
    控制台输出(msg);
    // 可以使用返回退出函数,但不返回值
    返回;
}
```

### 流程控制

**if-else if-else 语句:**
```ch
如果 (条件) {
    // 条件为真时执行
} 否则如果 (其他条件) {
    // 第一个条件为假,其他条件为真时执行
} 否则 {
    // 所有条件为假时执行
}
```

**示例:**
```ch
定义(整型) score = 85;
如果 (score >= 90) {
    控制台输出("成绩优秀");
} 否则如果 (score >= 80) {
    控制台输出("成绩良好");
} 否则如果 (score >= 70) {
    控制台输出("成绩中等");
} 否则如果 (score >= 60) {
    控制台输出("成绩及格");
} 否则 {
    控制台输出("成绩不及格");
}
```

### 控制台输入输出

**控制台输出:**
使用 `控制台输出()` 函数进行输出:
```ch
控制台输出("Hello World");
控制台输出(a + b);
```

**控制台输入:**
使用 `控制台输入()` 函数进行输入:
```ch
控制台输入(年龄);  // 从控制台读取输入到变量年龄
```

**文件操作:**

**文件写入:**
使用 `文件写入()` 函数创建或覆盖文件:
```ch
定义(字符串) content = "这是文件内容";
文件写入("example.txt", content);
```

**文件读取:**
使用 `文件读取()` 函数从文件读取内容:
```ch
定义(字符串) fileContent;
文件读取("example.txt", fileContent);
控制台输出("文件内容: " + fileContent);
```

**文件追加:**
使用 `文件追加()` 函数向文件末尾追加内容:
```ch
定义(字符串) additional = "追加的内容";
文件追加("example.txt", additional);
```

**完整示例:**
```ch
定义(空类型) 主函数() {
    // 写入文件
    定义(字符串) data = "Hello, File!";
    文件写入("test.txt", data);
   
    // 读取文件
    定义(字符串) content;
    文件读取("test.txt", content);
    控制台输出("读取的内容: " + content);
   
    // 追加内容
    文件追加("test.txt", "\n这是追加的内容");
}
```

**布尔类型操作:**
```ch
// 布尔型变量定义
定义(布尔型) isActive = 真;  // 真值
定义(布尔型) isEmpty = 假;   // 假值

// 布尔运算符
isActive && 假;  // 逻辑与:真 && 假 = 假
isActive || 假;  // 逻辑或:真 || 假 = 真
!isActive;       // 逻辑非:!真 = 假

// 基本运算符
定义(整型) a = 5;
定义(整型) b = 2;
定义(小数) x = 3.0;
定义(小数) y = 2.0;

// 算术运算符
a + b;   // 加法:5 + 2 = 7
a - b;   // 减法:5 - 2 = 3
a * b;   // 乘法:5 * 2 = 10
a / b;   // 除法:5 / 2 = 2
a % b;   // 取模:5 % 2 = 1
a ^ b;   // 乘方:5 ^ 2 = 25

x ^ y;   // 小数乘方:3.0 ^ 2.0 = 9.0
x ^ 2;   // 混合类型:3.0 ^ 2 = 9.0

// 比较运算返回布尔值
a < b;   // 返回 真
a == b;  // 返回 假
```

**数组操作:**
```ch
// 一维数组
定义(整型) arr[10];
控制台输出(arr[0]);     // 输出数组第一个元素
arr[5] = 100;            // 给数组元素赋值

// 动态数组大小(新增功能)
定义(整型) size = 5;
定义(整型) dynamicArr[size];     // 使用变量定义数组大小

定义(整型) n1 = 3, n2 = 4;
定义(整型) exprArr[n1 + n2];    // 使用表达式定义数组大小

// 多维数组(支持1-5维)
定义(整型) matrix[3][4];      // 二维数组 3x4
定义(整型) cube[2][2][2];     // 三维数组 2x2x2
定义(整型) arr5[2][2][2][2][2]; // 五维数组

// 多维动态数组
定义(整型) rows = 2, cols = 3;
定义(整型) dynamicMatrix[rows][cols];  // 多维动态数组

// 多维数组访问和赋值
matrix[1][2] = 42;               // 给二维数组元素赋值
cube[0][1][1] = 100;             // 给三维数组元素赋值
arr5[1][1][1][1][1] = 999;       // 给五维数组元素赋值

// 数组索引可以是变量
定义(整型) i = 3;
定义(整型) j = 2;
matrix[i][j] = 42;               // matrix[3][2] = 42
dynamicArr[i] = 42;               // 动态数组元素赋值
dynamicMatrix[i][j] = 42;         // 多维动态数组元素赋值
```

**结构体操作:**

**结构体定义:**
使用 `定义(结构体)` 关键字定义结构体类型:

**重要:结构体定义必须在主函数外部!**
```ch
// 结构体定义(在主函数外部)
定义(结构体) Person {
    整型 age;      // 年龄成员
    字符串 name;   // 姓名成员
    小数 score;    // 分数成员
};

定义(结构体) Point {
    整型 x;        // X坐标
    整型 y;        // Y坐标
    字符串 color;  // 颜色
};

// 主函数(在主函数外部)
定义(空类型) 主函数() {
    // 在主函数内部创建结构体变量和使用结构体
}
```

**结构体变量和成员访问:**
使用 `定义(结构体类型名)` 语法定义结构体变量,结构体变量只能通过以下方式初始化:

1. **无初始化器**:创建一个具有默认值的结构体变量
2. **同类型变量赋值**:从已存在的同类型结构体变量赋值

```ch
// 方式1:无初始化器(创建默认实例)
定义(Person) person1;  // 创建默认的Person实例,所有成员使用默认值
定义(Point) point1;    // 创建默认的Point实例,所有成员使用默认值

// 方式2:同类型变量赋值
定义(Person) person2 = person1;  // 正确:Person 类型赋值给 Person 类型
定义(Point) point2 = point1;    // 正确:Point 类型赋值给 Point 类型

// 错误示例:
// 定义(Person) person3 = "Person:age=25;name=张三;score=85.5";  // 错误:不能使用字面量初始化
// 定义(Point) point3 = person1;  // 错误:不能将 Person 类型赋值给 Point 类型

// 访问结构体成员
控制台输出("姓名: " + person1.name);      // 输出:空字符串(默认值)
控制台输出("年龄: " + person1.age);       // 输出:0(默认值)
控制台输出("分数: " + person1.score);     // 输出:0.0(默认值)

控制台输出("X坐标: " + point1.x);         // 输出:0(默认值)
控制台输出("Y坐标: " + point1.y);         // 输出:0(默认值)
控制台输出("颜色: " + point1.color);      // 输出:空字符串(默认值)
```

**结构体成员赋值:**
```ch
// 创建结构体变量
定义(Point) point1;

// 直接对结构体成员赋值
point1.x = 100;
point1.y = 200;
point1.color = "红色";

// 访问更新后的成员值
控制台输出("Point: x=" + point1.x + ", y=" + point1.y + ", color=" + point1.color);
```

**结构体变量赋值规则:**
- 结构体变量只能从同类型的变量初始化
- 不能使用字面量(如 "Person:age=25;name=张三")直接初始化结构体变量
- 不同类型的结构体变量之间不能互相赋值
- 结构体变量可以赋值给同类型的其他变量
- 支持直接对结构体成员进行赋值操作

**完整结构体示例:**
```ch
// 定义结构体
定义(结构体) Student {
    整型 id;
    字符串 name;
    小数 gpa;
    布尔型 isGraduate;
};

定义(空类型) 主函数() {
    // 创建学生对象(使用默认值)
    定义(Student) student1;  // 创建默认的Student实例
    定义(Student) student2;  // 创建另一个默认的Student实例
   
    // 结构体变量赋值(相同类型)
    定义(Student) student3 = student1;
   
    // 直接对结构体成员赋值
    student1.id = 1001;
    student1.name = "张三";
    student1.gpa = 3.8;
    student1.isGraduate = 假;
   
    // 输出学生信息
    控制台输出("学生1姓名: " + student1.name);  // 输出:张三
    控制台输出("学生1ID: " + student1.id);      // 输出:1001
    控制台输出("学生1GPA: " + student1.gpa);    // 输出:3.8
   
    控制台输出("学生3姓名: " + student3.name);  // 输出:空字符串(从 student1 赋值)
}
```

### 小数类型

使用 `小数` 关键字定义小数类型变量:
```ch
定义(小数) pi = 3.14;
定义(小数) radius = 5.0;
定义(小数) area = pi * radius * radius;
控制台输出("圆的面积: " + area);
```

### 循环语句

**while循环:**
```ch
定义(整型) i = 0;
当 (i < 5) {
    控制台输出("i = " + i);
    i = i + 1;
}
```

**for循环:**
```ch
定义(整型) j = 0;
对于 (j = 0; j < 3; j = j + 1) {
    控制台输出("j = " + j);
}
```

### 函数重载

解释器支持函数重载,即同名函数可以有不同的参数类型:

```ch
// 定义多个同名函数,参数类型不同
定义(整型) add(定义(整型) a, 定义(整型) b) {
    返回 a + b;
}

定义(小数) add(定义(小数) a, 定义(小数) b) {
    返回 a + b;
}

定义(字符串) add(定义(字符串) a, 定义(字符串) b) {
    返回 a + b;
}

// 调用时会根据参数类型自动选择合适的函数
定义(空类型) 主函数() {
    控制台输出(add(10, 20));      // 调用整型版本,输出30
    控制台输出(add(3.14, 2.86));  // 调用小数版本,输出6.0
    控制台输出(add("Hello", "World"));  // 调用字符串版本,输出HelloWorld
}
```

### 函数返回类型检查

所有函数都必须严格遵守返回类型:

```ch
// 正确的返回类型
定义(整型) getInt() {
    返回 42;  // 正确,返回整型
}

定义(小数) getDouble() {
    返回 3.14;  // 正确,返回小数
}

定义(布尔型) getBool() {
    返回 真;  // 正确,返回布尔型
}

定义(空类型) print() {
    控制台输出("Hello");
    返回;  // 正确,空类型函数可以使用返回退出
}

// 错误的返回类型(会导致编译错误)
定义(整型) wrongFunc() {
    返回 3.14;  // 错误:返回小数,但声明为整型
}

定义(空类型) wrongFunc2() {
    返回 42;  // 错误:空类型函数不能返回值
}
```

## 中文关键字与 C++ 关键字对照表

| 中文关键字 | C++ 关键字 | 说明 |
|----------|-----------|------|
| 定义      | -         | 用于变量和函数定义 |
| 整型      | int       | 整数类型 |
| 字符串    | string    | 字符串类型 |
| 空类型    | void      | 无返回值类型 |
| 主函数    | main      | 程序入口函数 |
| 如果      | if        | 条件判断 |
| 否则      | else      | 条件判断的分支 |
| 否则如果   | else if   | 条件判断的中间分支 |
| 控制台输出 | cout      | 输出到控制台 |
| 控制台输入 | cin       | 从控制台输入 |
| 返回      | return    | 函数返回值 |
| 小数      | double    | 小数类型 |
| 布尔型     | bool      | 布尔类型 |
| 真        | true      | 布尔真值 |
| 假        | false     | 布尔假值 |
| 当        | while     | 循环语句 |
| 对于      | for       | 循环语句 |
| 文件读取   | -         | 从文件读取内容 |
| 文件写入   | -         | 向文件写入内容 |
| 文件追加   | -         | 向文件追加内容 |
| 结构体    | struct    | 结构体关键字(用于定义(结构体)) |
| 数组      | -         | 数组类型关键字 |
| ^         | pow       | 乘方运算符 |
| +, -, *, /, % | +, -, *, /, % | 算术运算符 |
| &&, \|\| | &&, \|\| | 逻辑运算符 |
| ==, !=, <, >, <=, >= | ==, !=, <, >, <=, >= | 比较运算符 |

## 运行/解析流程

1. **读取文件**:读取 `.ch` 文件内容
2. **词法分析**:将源代码转换为 Token 序列
3. **语法分析**:构建抽象语法树 (AST)
4. **执行**:遍历 AST 并执行相应的操作
5. **输出结果**:将执行结果输出到控制台

## 示例代码

### 示例 1:Hello World

**文件名:** `examples/hello.ch`

```ch
定义(空类型) 主函数() {
    控制台输出("Hello World!");
}
```

**运行结果:**
```
Hello World!
```

### 示例 2:基本运算

**文件名:** `examples/calculator.ch`

```ch
定义(空类型) 主函数() {
    定义(整型) a = 10;
    定义(整型) b = 20;
    定义(整型) sum = a + b;
    定义(整型) product = a * b;
    控制台输出("a + b = " + sum);
    控制台输出("a * b = " + product);
}
```

**运行结果:**
```
a + b = 30
a * b = 200
```

### 示例 3:条件判断

**文件名:** `examples/conditions.ch`

```ch
定义(空类型) 主函数() {
    定义(整型) score = 85;
   
    如果 (score >= 90) {
        控制台输出("成绩优秀");
    } 否则如果 (score >= 80) {
        控制台输出("成绩良好");
    } 否则如果 (score >= 70) {
        控制台输出("成绩中等");
    } 否则如果 (score >= 60) {
        控制台输出("成绩及格");
    } 否则 {
        控制台输出("成绩不及格");
    }
}
```

**运行结果:**
```
成绩良好
```

### 示例 4:函数重载

**文件名:** `examples/function_overload.ch`

```ch
定义(整型) add(定义(整型) a, 定义(整型) b) {
    返回 a + b;
}

定义(小数) add(定义(小数) a, 定义(小数) b) {
    返回 a + b;
}

定义(字符串) add(定义(字符串) a, 定义(字符串) b) {
    返回 a + b;
}

定义(空类型) 主函数() {
    控制台输出(add(10, 20));      // 调用整型版本
    控制台输出(add(3.14, 2.86));  // 调用小数版本
    控制台输出(add("Hello", "World"));  // 调用字符串版本
}
```

**运行结果:**
```
30
6
HelloWorld
```

### 示例 5:结构体操作

**文件名:** `examples/struct_demo.ch`

```ch
定义(结构体) Point {
    整型 x;
    整型 y;
    字符串 color;
};

定义(空类型) 主函数() {
    // 创建结构体变量
    定义(Point) point1;
   
    // 直接对结构体成员赋值
    point1.x = 100;
    point1.y = 200;
    point1.color = "红色";
   
    // 输出结构体成员
    控制台输出("Point: x=" + point1.x + ", y=" + point1.y + ", color=" + point1.color);
}
```

**运行结果:**
```
Point: x=100, y=200, color=红色
```

### 示例 6:数组操作

**文件名:** `examples/array_demo.ch`

```ch
定义(空类型) 主函数() {
    // 数组定义和初始化
    定义(整型) numbers[5];
    定义(整型) i = 0;
   
    // 给数组赋值
    对于 (i = 0; i < 5; i = i + 1) {
        numbers[i] = (i + 1) * 10;
    }
   
    // 输出数组内容
    控制台输出("数组内容:");
    对于 (i = 0; i < 5; i = i + 1) {
        控制台输出("numbers[" + i + "] = " + numbers[i]);
    }
   
    // 数组计算
    定义(整型) sum = 0;
    对于 (i = 0; i < 5; i = i + 1) {
        sum = sum + numbers[i];
    }
    控制台输出("数组总和: " + sum);
}
```

**运行结果:**
```
数组内容:
numbers[0] = 10
numbers[1] = 20
numbers[2] = 30
numbers[3] = 40
numbers[4] = 50
数组总和: 150
```

### 示例 7:文件操作

**文件名:** `examples/file_demo.ch`

```ch
定义(空类型) 主函数() {
    // 写入文件
    定义(字符串) content = "Hello, File!";
    文件写入("test.txt", content);
   
    // 读取文件
    定义(字符串) fileContent;
    文件读取("test.txt", fileContent);
    控制台输出("读取的内容: " + fileContent);
   
    // 追加内容
    文件追加("test.txt", "\n这是追加的内容");
}
```

**运行结果:**
```
读取的内容: Hello, File!
```

### 示例 8:作用域限制

**文件名:** `examples/scope_test.ch`

```ch
// 全局作用域:只能定义变量和结构体
定义(整型) globalVar = 100;

定义(结构体) GlobalStruct {
    整型 value;
};

定义(空类型) 主函数() {
    // 函数内部可以执行各种操作
    控制台输出("在函数内部可以执行各种操作");
    控制台输出("全局变量值: " + globalVar);
   
    // 函数内定义的变量
    定义(整型) localVar = 50;
    控制台输出("局部变量值: " + localVar);
   
    // 文件操作(只在函数内允许)
    文件写入("test.txt", "这是函数内的操作");
}
```

**注意:** 如果在全局作用域中尝试执行文件读写等操作,会产生错误:
```
在全局作用域中不允许执行此操作,只能定义变量或结构体 在第 X 行
```

## 字符编码支持

**ASCII码表适配:**
- 完全支持ASCII字符(0-127)
- 自动兼容中文字符(128+)
- 支持UTF-8编码环境下的所有字符

**乱码修复实现原理:**
为确保中文关键字、中文输出内容和中文报错信息能正常显示,解释器在启动时会尝试设置中文 locale:

1. 首先尝试设置 `zh_CN.UTF-8` 编码的 locale
2. 如果失败,尝试设置 `Chinese` locale
3. 如果仍然失败,使用默认 locale
4. Windows环境下自动设置控制台代码页为65001(UTF-8)

这样可以保证在不同操作系统环境下(Windows、Linux、macOS)都能正确显示中文。

## 核心功能

1. **中文关键字**:所有关键字全部使用中文,无任何英文关键字
2. **数据类型支持**:
   - 基础类型:整型、字符串、小数、布尔型
   - 字面量:真、假(布尔型字面量)
   - 完整的布尔运算:&&、||、!运算符
3. **变量定义**:支持整型、字符串、小数、布尔型变量的定义与初始化
4. **多维数组支持**:
   - 支持1-5维数组,最多5维
   - 语法类似C/C++:`定义(整型) arr[3][4][5];`
   - 完整的数组定义、初始化、访问和赋值功能
   - 支持动态索引:`arr[i][j]` (i,j为变量)
   - 数组元素自动初始化为0
5. **函数定义**:支持无返回值和有返回值的函数定义
6. **函数重载**:支持同名函数不同参数类型
7. **函数作用域限制**:全局作用域只允许变量定义和结构体定义
8. **函数返回类型检查**:确保函数返回类型与定义一致
9. **智能类型系统**:
   - 整型运算返回整型(如:10 + 3 = 13)
   - 浮点数运算返回浮点数(如:3.14 * 2 = 6.28)
   - 混合运算支持类型自动转换
10. **布尔逻辑运算**:
    - 逻辑与:`&&` 运算符
    - 逻辑或:`||` 运算符
    - 逻辑非:`!` 运算符
    - 比较运算:`<、>、<=、>=、==、!=`,返回布尔值
11. **基本运算**:支持加减乘除、取模、乘方、比较运算、逻辑运算
12. **控制台输入输出**:支持从控制台输入和输出变量值、字符串
13. **文件读写操作**:
    - 文件写入:创建或覆盖文件内容
    - 文件读取:从文件读取内容到变量
    - 文件追加:在文件末尾追加内容
    - 支持复杂的表达式作为文件名和内容
14. **流程控制**:if-else if-else条件判断、while/for循环
15. **结构体支持**:
    - 结构体定义:使用 `定义(结构体)` 关键字
    - 结构体变量:支持结构体类型的变量实例化
    - 成员访问:通过 `.` 运算符访问结构体成员
    - 成员赋值:支持直接对结构体成员进行赋值操作
    - 完整类型支持:整型、字符串、小数、布尔型成员
16. **主函数机制**:以 `主函数()` 作为程序唯一入口
17. **ASCII兼容**:完全支持ASCII码表和中文字符
18. **精确错误定位**:所有错误都包含行号和列号信息
19. **严格错误处理**:移除所有"假设"和"简化处理",提供详细错误信息

## 使用方法

### 编译

#### 方式一:直接使用g++编译

```bash
# 编译chplus解释器
g++ main.cpp src/lexer/lexer.cpp src/parser/parser.cpp src/executor/interpreter.cpp -std=c++17 -o chplus.exe
```

#### 方式二:使用CMake编译(推荐)

```bash
# 创建构建目录
mkdir build && cd build

# 配置项目(Linux/MacOS)
cmake ..

# 配置项目(Windows MinGW)
cmake -G "MinGW Makefiles" ..

# 构建项目
cmake --build .

# 运行程序
./chplus.exe ../examples/hello.ch
```

#### 2. 代码格式化工具

chplus集成了智能代码格式化功能,支持:

**自动格式化(默认):**
- 修复松散格式(如 `定义( 空类型 )主函数( )` → `定义(空类型)主函数()`)
- 标准化缩进和换行
- 中文符号自动转换为英文符号
- 保持语法错误不修改
- 智能换行:`{` 不换行,`}` 必须换行

**命令行选项:**
- `-a`               : 自动格式化并覆盖原文件
- `--no-format, -n` : 不自动格式化代码
- `--help, -h`      : 显示帮助信息

**格式化效果示例:**

**输入(松散格式):**
```ch
定义( 空类型 )主函数( )
{
控制台输出 (  "Hello World" )   ;
}
```

**输出(标准格式):**
```ch
定义(空类型)主函数(){
    控制台输出("Hello World");
}
```

### 运行

```bash
# 标准运行(自动格式化)
./chplus.exe examples/hello.ch

# 不自动格式化运行
./chplus.exe --no-format examples/hello.ch

# 查看帮助
./chplus.exe --help
```

## 错误处理

解释器的所有报错输出均使用中文,所有错误都包含精确的行号信息:

**错误信息格式:**
- 错误类型和具体原因
- 错误位置(行号)
- 详细的错误说明

**示例错误信息:**
```
错误: 变量未定义: x 在第 5 行
错误: 数组未定义: dp 在第 8 行
错误: 除零错误 在第 15 行
错误: 无效的数组索引: abc 在第 20 行
错误: 不支持的运算符: ^ 在第 25 行
错误: 函数未定义: add(整型, 整型) 在第 30 行
错误: 返回类型不匹配: 期望 整型,但实际返回 小数 在第 35 行
错误: 在全局作用域中不允许执行此操作,只能定义变量或结构体 在第 40 行
```

**改进的错误检查:**
- &#9989; 变量存在性检查:访问未定义变量会报错
- &#9989; 数组边界检查:防止访问不存在的数组元素
- &#9989; 类型检查:确保运算类型兼容
- &#9989; 除零检查:防止除零运算
- &#9989; 语法错误检查:确保代码语法正确
- &#9989; 函数重载检查:确保函数参数类型匹配
- &#9989; 返回类型检查:确保函数返回类型与定义一致
- &#9989; 作用域检查:确保全局作用域只允许定义操作

**严格的错误处理:**
- 移除了所有"假设"和"简化处理"代码
- 添加了完整的类型验证
- 改进了数组操作的错误处理
- 优化了表达式求值的错误检测
- 添加了函数重载的错误处理
- 改进了返回类型检查

## 注意事项

1. 解释器支持完整的数组功能和智能类型系统
2. 变量类型支持整型、字符串、小数、布尔型类型
3. 所有错误都有精确的行号定位
4. 建议使用 UTF-8 编码保存 `.ch` 文件,以避免字符编码问题
5. 结构体变量只能通过两种方式初始化:无初始化器(创建默认实例)或同类型变量赋值
6. 支持直接对结构体成员进行赋值操作
7. **函数作用域限制**:全局作用域(主函数外部)只能定义变量和结构体,不允许执行其他操作
8. **函数重载**:同名函数必须有不同的参数类型,调用时会自动选择合适的函数
9. **返回类型检查**:所有函数都必须严格遵守返回类型,不匹配会报错
10. **空类型函数**:可以使用返回语句退出函数,但不能返回值

## 未来计划

1. 增加更多数据类型支持(如枚举类型等)
2. 完善函数参数列表的解析
3. 增加更多流程控制语句(如 switch 语句等)
4. 增加调试功能和断点支持
5. 优化性能,支持更大规模的程序

## 许可证
本项目采用 **GNU AGPL v3.0 + Commons Clause 1.0** 协议授权,核心规则如下:
1.  &#127379; 个人非商业用途可自由使用、修改、分发
2.  &#128683; 禁止任何形式的商业使用(包括出售、出租、作为商业产品组件等)
3.  &#128295; 修改后的衍生作品必须:
    - 保留原项目版权和许可证信息
    - 以相同协议开源并附带完整源代码
    - 明确标注衍生作品与原项目的差异,并提供原项目源库链接
4.  &#128196; 完整许可证内容请查看项目根目录下的 `LICENSE` 文件

原项目源库:[https://github.com/abcdefgjh-li/chplus]

chplus.zip

355.27 KB, 下载次数: 26, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
lswdla + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

沙发
y2500004yy 发表于 2026-1-30 00:10
习惯了看代码,再看这个有点头大,对新手应该不错吧
3#
haibo7798 发表于 2026-1-30 00:15
4#
wen4610078 发表于 2026-1-30 05:27
对于小白学习编程来说这个&#128070;&#127995;太有用了
5#
qhczdy 发表于 2026-1-30 07:51
谢谢分享
6#
lswdla 发表于 2026-1-30 07:55
完善好了,就再弄个汇编语言的吧
7#
zhjsh999 发表于 2026-1-30 08:17
小白路过
8#
残夕若此 发表于 2026-1-30 09:19
压缩包的少依赖 git的也编译报错
9#
xuepojie 发表于 2026-1-30 09:31
虽然看不懂,但是还是感谢楼主的分享和分析
10#
xjlyg 发表于 2026-1-30 09:37
感谢,正好拿来学习
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-1-30 10:00

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表