40 KiB
40 KiB
Tree-sitter TSF 语法解析器
这个项目为你的 TSF 语言创建了一个 Tree-sitter 语法解析器,支持完整的 TSF 语法特性。
✨ 完整语法特性
1. 🗨️ 注释(3 种方式)
// 行注释
{ 块注释1 }
(* 块注释2 *)
2. 🔢 数字格式
// 基础数字
100
1.2232442
// 科学记数法
1E2
-3.4e34
2.4e-23
// 不同进制
0x1A // 十六进制
0b100 // 二进制
0o64 // 八进制
// 带符号数字
+123
-456.789
3. 📝 字符串和字面量
// 字符串
'string0'
"string1"
"escaped \"quotes\" and \\backslashes"
// 特殊字面量
nil // 空值
-INF // 负无穷大
+INF // 正无穷大
NAN // 非数
false // 布尔false
true // 布尔true
4. 📊 数组构造(支持多层嵌套)
TSF 的数组语法使用 array() 构造函数,支持任意层级的嵌套:
基础数组类型
// 简单元素数组
array(1, 2, 3)
array("a", "b", "c")
array(1, "abc", true, nil)
// 键值对数组
array("key1": "value1", "key2": "value2")
array("name": "Alice", "age": 25, "active": true)
// 元组数组
array((1, "first"), (2, "second"), (3, "third"))
array(("id": 1, "name": "Alice"), ("id": 2, "name": "Bob"))
// 空数组
array()
复杂嵌套示例
// 多维数组
matrix := array(
array(1, 2, 3),
array(4, 5, 6),
array(7, 8, 9)
);
// 键值对嵌套
config := array(
"database": array(
"host": "localhost",
"port": 5432,
"tables": array("users", "products", "orders")
),
"cache": array(
"redis": array("host": "redis.local", "port": 6379),
"enabled": true
)
);
// 混合结构:键值对 + 元组 + 嵌套数组
complex_data := array(
"users": array(
("id": 1, "name": "Alice", "scores": array(85, 92, 78)),
("id": 2, "name": "Bob", "scores": array(91, 87, 95))
),
"metadata": array(
"total": 2,
"stats": array(
("mean": 88.5, "data": array(1, 2, 3)),
("max": 95, "data": (true, false, nil))
)
)
);
数组访问和操作
// 索引访问
item := arr[0];
value := matrix[1][2];
nested := config["database"]["tables"][0];
// 切片访问
slice := arr[1:5]; // 从索引1到4
head := arr[:3]; // 前3个元素
tail := arr[2:]; // 从索引2到末尾
// 数组赋值
arr[index] := new_value;
matrix[i][j] := data;
config["setting"] := "value";
5. ➕ 运算符
算术运算符
+ - * / % // 基本运算
+= -= /= *= // 复合赋值
++ -- // 自增自减(前缀和后缀)
mod // 取余(同%)
div // 除取整,如7 div 3 = 2
^ // 求幂,如2^3 = 8
~ // 求对数,8~2=3
! // 求导数,!A=1/A
自增自减运算符说明:
- 前缀自增自减:
++a,--a- 作为独立的自增自减语句 - 后缀自增自减:
a++,a--- 作为表达式语句使用
function example();
begin
// 前缀自增自减语句
++counter;
--index;
// 后缀自增自减表达式语句
counter++;
index--;
// 在表达式中使用
result := ++a * 2; // 前缀:先自增,再使用
value := b++ * 2; // 后缀:先使用,再自增(作为表达式)
// 对象成员的自增自减
++obj.count; // 前缀语句
obj.count++; // 后缀表达式语句
end;
字符串连接运算符
$ // 万能连接符,可以连接任何类型
$ 连接符示例:
// 基础连接
message := "Hello" $ " " $ "World"; // 结果: "Hello World"
info := "Count: " $ 42 $ " items"; // 结果: "Count: 42 items"
// 连接不同类型
status := "User " $ user_id $ " is " $ (is_active ? "active" : "inactive");
// 在表达式中使用
calculation := "Result: " $ (a + b) $ " = " $ result;
// 函数调用连接
log_entry := getTimestamp() $ ": " $ getMessage() $ " [" $ getLevel() $ "]";
// 对象属性连接
full_name := person.firstName $ " " $ person.lastName;
// raise语句中使用
raise "Error " $ error_code $ ": " $ error_message;
// echo语句中使用
echo "Processing " $ current_index $ " of " $ total_count $ " items";
矩阵运算符
` // 矩阵转置(前缀)
| // 矩阵列连接
Union // 矩阵行连接
:| // 非完全矩阵列连接
! // 矩阵求逆与广义逆(前缀)
:* // 矩阵乘法
:\\ // 矩阵左除
:^ // 矩阵乘方
矩阵运算符示例:
// 矩阵转置(前缀)
A := array((1,2,3),(4,5,6)); // 2x3矩阵
B := `A; // 转置为3x2矩阵: ((1,4),(2,5),(3,6))
// 矩阵列连接
matrix1 := array((1,2),(3,4)); // 2x2矩阵
matrix2 := array((5,6),(7,8)); // 2x2矩阵
combined := matrix1 | matrix2; // 2x4矩阵: ((1,2,5,6),(3,4,7,8))
// 矩阵行连接
row_combined := matrix1 Union matrix2; // 4x2矩阵
// 矩阵求逆(前缀)
identity := !A; // A的逆矩阵
// 矩阵乘法
result := matrix1 :* matrix2; // 矩阵乘法
// 矩阵左除
solution := A :\\ b; // 求解线性方程组 Ax = b
// 矩阵乘方
power_matrix := A :^ 3; // A的3次幂
// 复杂矩阵运算组合(前缀转置)
complex_result := `(A :* B) | (C Union D);
// 嵌套转置运算
double_transpose := ``A; // 转置的转置,等于原矩阵
mixed_ops := `(!A) :* B; // 先求逆,再转置,然后矩阵乘法
集合运算符
union // 集合并集
union2 // 集合并集2
minus // 集合差集
intersect // 集合交集
集合运算符示例:
// 集合定义
setA := array(1, 2, 3, 4, 5);
setB := array(4, 5, 6, 7, 8);
setC := array(2, 4, 6, 8, 10);
// 集合并集
union_result := setA union setB; // 结果: array(1,2,3,4,5,6,7,8)
// 集合并集2(可能有不同的语义)
union2_result := setA union2 setB;
// 集合差集
diff_result := setA minus setB; // 结果: array(1,2,3)
// 集合交集
intersect_result := setA intersect setB; // 结果: array(4,5)
// 复杂集合运算
complex_set := (setA union setB) intersect setC; // ((A∪B)∩C)
// 集合复合赋值
setA union= setB; // setA = setA union setB
setA minus= setC; // setA = setA minus setC
setA intersect= setB; // setA = setA intersect setB
// 对象成员的集合运算
obj.values union= new_values;
data.items intersect= valid_items;
复合赋值运算符(扩展)
+= -= *= /= // 基础算术复合赋值
union= // 集合并集复合赋值
union2= // 集合并集2复合赋值
minus= // 集合差集复合赋值
intersect= // 集合交集复合赋值
逻辑运算符
.&& and // 与
.|| or // 或
.!! not // 非
位运算符
.& // 位与
.| // 位或
.! // 位非
.^ // 位异或
shl // 位左移
rol // 左循环移位
shr // 位右移
ror // 右循环移位
比较运算符
= // 等于
<> // 不等于
< > <= >= // 大小比较
三元条件运算符
// 基本三元表达式
result := condition ? value_if_true : value_if_false;
// 实际示例
max := a > b ? a : b;
status := age >= 18 ? "adult" : "minor";
price := isMember ? originalPrice * 0.8 : originalPrice;
// 嵌套三元表达式
grade := score >= 90 ? "A" :
score >= 80 ? "B" :
score >= 70 ? "C" : "F";
// 在数组中使用
data := array(
condition1 ? "option1" : "default1",
condition2 ? array(1, 2, 3) : array(),
x > 0 ? (positive_val, "positive") : (negative_val, "negative")
);
6. 📦 变量声明
a := nil; // 普通赋值
const ca = 123; // 常量声明
global ga := array(1, 2, 3); // 全局变量声明+初始化
global ga1; // 只声明全局变量
7. 📤 解包(Destructuring)赋值
// 基础数组解包
[a, b, c] := array(1, 2, 3); // a=1, b=2, c=3
// 函数返回值解包
[x, y] := getCoordinates(); // 解包函数返回的数组
[name, age, email] := getUserInfo(user_id); // 解包用户信息
// 嵌套数组解包
[first, second, third] := matrix[0]; // 解包矩阵第一行
[user_data] := config["users"][0]; // 解包配置中的用户数据
// 复杂表达式解包
[min_val, max_val] := calculateRange(data); // 解包计算结果
[status, message, data] := processRequest(); // 解包处理结果
// 在函数中使用解包
function processUserData();
begin
[id, name, age, scores] := getUserById(123);
// 处理解包后的数据
if age >= 18 then
echo "Adult user: " $ name $ " (ID: " $ id $ ")";
// 解包嵌套数据
[math, english, science] := scores;
average := (math + english + science) / 3;
return array("name": name, "average": average);
end;
8. 🔀 条件语句
// if语句
if aaa then
begin
// 代码块
end
else if bbb then
begin
// 代码块
end
else begin
// 代码块
end
// 单行if语句
if condition then statement;
if x > 0 then result := x;
// case语句
case age of
10: println("10");
11,12: begin
println("11,12");
end
else
println("case default");
end;
9. 🔄 循环语句
// for...in 循环
for k,v in data do
begin
if v = "c" then continue;
process(k, v);
end;
// for...to 循环(递增)
for i:=0 to length(data) do
begin
if i = 10 then break;
process(data[i]);
end
// for...downto 循环(递减)
for i:=100 downto 0 do
println(i);
// while 循环
while condition do
begin
// 代码块
end;
// repeat...until 循环
a := 1;
repeat
a++;
until a > 10;
return a;
10. 🎛️ 控制流
break; // 跳出循环
continue; // 继续下一次循环
return value; // 返回值
return; // 无返回值返回
11. 🔑 关键字语句
TSF 提供了一些专用的关键字语句,用于特定的操作。
Echo 语句 - 输出打印
// 输出多个值(用逗号分隔)
echo "Hello", " ", "World"; // 输出:Hello World
echo "Value: ", x, " Type: ", type; // 输出多个值
echo "Count:", count + 1, func(); // 表达式和函数调用
// 输出单个值
echo variable; // 输出单个变量
echo "Simple message"; // 输出字符串
echo array(1, 2, 3); // 输出数组
// 配合$连接符使用
echo "Processing " $ current_index $ " of " $ total_count $ " items";
echo "User " $ user_name $ " logged in at " $ timestamp;
Raise 语句 - 异常抛出
// 基本异常抛出
raise "Error message"; // 抛出字符串消息
raise error_variable; // 抛出变量值
raise getErrorMessage(); // 抛出函数返回值
// 使用表达式
raise "Error: " + error_code; // 字符串拼接
raise "Error code " $ error_code $ " occurred"; // 使用$连接符
// 复杂异常消息构建
raise "User " $ user_id $ " permission denied at " $ getTimestamp();
raise "Invalid input: expected " $ expected_type $ ", got " $ actual_type;
// 条件性异常抛出
if invalid_input then
raise "Invalid input provided";
if data = nil then
raise "Data cannot be nil";
12. 🔍 判断语法
TSF 提供了专门的判断语法,用于类型检查和成员检查。
is class() - 类型判断
// 基础类型判断
obj is class(MyClass) // 判断obj是否是MyClass的实例
instance is class(Person) // 判断instance是否是Person类型
data is class(Array) // 判断data是否是Array类型
// 使用qualified identifier
obj is class(namespace.ClassName) // 带命名空间的类名
instance is class(mymodule.Person) // 模块中的类
// 在条件语句中使用
if obj is class(Person) then
echo "This is a Person object";
else
echo "Not a Person object";
// 在三元表达式中使用
type_name := obj is class(Person) ? "Person" : "Other";
message := data is class(Array) ? "Array data" : "Non-array data";
in - 成员检查
// 基础成员检查
1 in array(1, 2, 3) // 检查数字是否在数组中
"apple" in array("apple", "banana") // 检查字符串是否在数组中
item in my_array // 检查元素是否在变量数组中
// 复杂表达式检查
(x + y) in valid_values // 表达式结果检查
user.id in authorized_ids // 对象属性检查
getValue() in allowed_values // 函数返回值检查
// 嵌套数组检查
target in data["items"]["list"] // 检查嵌套数组成员
item in config["allowed"]["types"] // 配置数组检查
// 在条件语句中使用
if value in valid_values then
echo "Value is valid";
else
raise "Invalid value: " $ value;
13. 📝 表达式语句
TSF 支持将表达式作为独立的语句使用,这在函数调用和计算中非常有用:
function example();
begin
// 表达式语句 - 函数调用
func();
obj.method();
// 表达式语句 - 自增自减(后缀)
counter++;
index--;
obj.value++;
// 表达式语句 - 数学运算(可能有副作用)
x + y;
a * b + c;
// 表达式语句 - 矩阵运算
`matrix; // 转置操作(前缀)
matrix1 :* matrix2; // 矩阵乘法
// 表达式语句 - 集合运算
setA union setB;
// 表达式语句 - 三元条件
condition ? action1() : action2();
// 表达式语句 - 复杂嵌套
obj.method().getValue() + process(data);
end;
14. 🔧 函数定义
// 参数不指定类型(用逗号分隔)
function syntax_func(a, b);
begin
// 函数体
end
// 参数指定类型(用分号分隔)
function syntax_func(a: real; b: array of string);
begin
// 函数体
end;
// 参数带默认值(用分号分隔)
function syntax_func(a: real = 1.0; c: string = "123")
begin
var1 := 123;
end;
// 参数带默认值但无类型
function syntax_func(a = 1; b = 2)
begin
// 函数体
end
// 返回类型
function calculate(x: real; y: real): real;
begin
return x + y;
end;
15. 📞 函数调用
// 无参数调用
test();
// 带参数调用
func(arg1, arg2);
println("{} == {}", k, ret);
// 链式调用
obj.method1().method2().method3();
// 嵌套调用
result := outer_func(inner_func(param));
函数指针调用
TSF 支持函数指针的调用,使用 ## 语法来调用通过指针引用的函数。
// 函数指针调用语法
##pointer_func(param1, param2);
// 实际使用示例
function add(a: integer; b: integer): integer;
begin
return a + b;
end;
function multiply(a: integer; b: integer): integer;
begin
return a * b;
end;
function processWithCallback(x: integer; y: integer; callback_ptr);
begin
// 使用函数指针调用
result := ##callback_ptr(x, y);
echo "Callback result: " $ result;
return result;
end;
function demonstrateFunctionPointers();
begin
// 获取函数指针
add_ptr := @add; // 获取add函数的指针
mul_ptr := @multiply; // 获取multiply函数的指针
// 直接调用函数指针
sum := ##add_ptr(5, 3); // 等价于 add(5, 3)
product := ##mul_ptr(4, 6); // 等价于 multiply(4, 6)
echo "Sum: " $ sum; // 输出: Sum: 8
echo "Product: " $ product; // 输出: Product: 24
// 将函数指针作为参数传递
result1 := processWithCallback(10, 20, add_ptr);
result2 := processWithCallback(10, 20, mul_ptr);
return array("sum": result1, "product": result2);
end;
// 函数指针数组的使用
function useFunctionPointerArray();
begin
// 创建函数指针数组
operations := array(@add, @multiply);
// 通过数组索引调用函数指针
for i := 0 to length(operations) - 1 do
begin
operation := operations[i];
result := ##operation(7, 3);
echo "Operation " $ i $ " result: " $ result;
end;
return operations;
end;
函数指针调用特性:
- 调用语法:
##pointer_name(arguments) - 指针获取:使用
@function_name获取函数指针 - 参数传递:支持任意数量和类型的参数
- 返回值:函数指针调用可以有返回值
- 动态调用:可以在运行时决定调用哪个函数
- 方法指针:支持对象方法的指针调用
- 数组存储:函数指针可以存储在数组中进行批量操作
16. 🏗️ 类系统
基础类声明
// 声明一个简单的类
type Base = class
end; // 分号可有可无
// 继承一个类
type Child = class(Base)
end
成员变量声明
type MyClass = class
public
member1; // 直接声明
private
member2: string; // 有类型的声明
protected
[weakref]member3; // 有[tag]的声明,weakref表示弱引用
[weakref]member4: obj; // 带类型和标签的声明
end;
方法声明
type MyClass = class
public
// 构造和析构方法
function Create(); // 默认构造方法
function Destroy(); // 默认析构方法
// 类内实现的方法
function GetValue();
begin
return member1;
end
// 只声明的方法(类外实现)
function Process(data: string);
// 带修饰符的方法
function VirtualFunc();virtual; // 虚方法
function OverloadFunc();overload; // 重载方法
function OverloadFunc(a: integer);overload; // 重载方法
private
member1: integer;
end;
操作符重载
TSF 支持类的操作符重载,允许自定义类如何响应特定的操作符。
type MyClass = class
public
// 构造函数
function Create();
// 操作符重载声明
function operator[](index: integer); // 数组访问操作符重载
function operator+(other: MyClass); // 加法操作符重载
function operator=(other: MyClass); // 赋值操作符重载
function operator<>(other: MyClass); // 不等于操作符重载
function operator*(other: MyClass); // 乘法操作符重载
// 类内实现的操作符重载
function operator++(); // 前缀自增操作符重载
begin
value := value + 1;
return self;
end
private
value: integer;
data: array of string;
end;
类外操作符重载实现:
// 类外实现操作符重载
function operator MyClass.[](index: integer);
begin
if index >= 0 and index < length(data) then
return data[index]
else
raise "Index out of bounds: " $ index;
end;
function operator MyClass.+(other: MyClass);
begin
result := new MyClass();
result.value := self.value + other.value;
return result;
end;
function operator MyClass.=(other: MyClass);
begin
return self.value = other.value;
end;
function operator MyClass.*(other: MyClass);
begin
result := new MyClass();
result.value := self.value * other.value;
return result;
end;
操作符重载使用示例:
function testOperatorOverloading();
begin
// 创建对象
obj1 := new MyClass();
obj2 := new MyClass();
// 使用重载的操作符
item := obj1[0]; // 调用 operator[]
sum := obj1 + obj2; // 调用 operator+
product := obj1 * obj2; // 调用 operator*
// 比较操作符
if obj1 = obj2 then // 调用 operator=
echo "Objects are equal";
if obj1 <> obj2 then // 调用 operator<>
echo "Objects are not equal";
// 自增操作符
++obj1; // 调用 operator++
return sum;
end;
支持的操作符重载:
- 数组访问:
[] - 算术运算:
+-*/%^ - 比较运算:
=<><><=>= - 自增自减:
++-- - 赋值运算:
:= - 其他运算:根据需要可以重载更多操作符
类外方法实现
// 类外实现方法
function MyClass.Create();
begin
member1 := 123;
end;
function MyClass.Process(data: string);
begin
result := data + " processed";
end;
// 带修饰符的类外实现
function MyClass.VirtualFunc();virtual;
begin
// 虚方法实现
end;
17. 🆕 对象创建和成员访问
对象创建
// 创建无参数对象
obj := new MyClass();
// 创建带参数对象
obj := new MyClass(param1, param2);
// 使用限定名称创建对象
obj := new package.MyClass();
// 创建对象并立即使用
result := new Calculator().add(1, 2);
成员访问和操作
// 成员访问
value := obj.property;
nested_value := obj.nested.property;
// 成员赋值
obj.property := 123;
obj.nested.value := "test";
// 方法调用
obj.method();
result := obj.calculate(10, 20);
// 链式调用
result := obj.method1().method2().getValue();
// 成员自增自减
obj.count++;
++obj.value;
// 成员复合赋值
obj.value += 10;
obj.score *= 1.1;
// 成员数组访问
item := obj.data[index];
obj.array[i] := new_value;
18. 📦 Unit(模块)系统
Unit 声明语法
unit UnitName; // unit 声明,分号必须
interface // 对外接口部分
// 公开的变量、常量和函数声明
implementation // 实现部分
// 私有变量、常量和函数实现
initialization // 初始化部分(可选)
// 单元加载时执行的代码
finalization // 析构部分(可选)
// 单元卸载时执行的代码
end. // 结束标记,点号必须
使用 Unit
uses UnitName; // 引入单个单元
uses Unit1, Unit2, Unit3; // 引入多个单元
完整 Unit 示例
unit DeMo_Unit_Test01;
interface
var Ua, Ub;
const CS = 888;
function addv();
function NumbJO(v);
function print();
implementation
const CN = array("奇数", "偶数");
var Uc;
function print();
begin
echo "当前值-Ua:", Ua, " Ub:", Ub, " Uc:", Uc, " CS:", CS;
end
function addv();
begin
Ua += 10;
Uc += 1;
end;
function NumbJO(v);
begin
if (v mod 2) = 0 then
echo v, "是一个", CN[1];
else
echo v, "是一个", CN[0];
end;
initialization
Ua := 100;
Ub := "Tinysoft Unit";
Uc := 1;
finalization
echo "DeMo_Unit_Test01 End.";
end.
19. 🔍 数组索引和切片访问
// 基础索引访问
item := arr[0];
value := matrix[i][j];
// 嵌套数组访问
user := data["users"][0];
score := user["scores"][1];
// 切片访问
slice := arr[1:5]; // 从索引1到4
head := arr[:3]; // 前3个元素
tail := arr[2:]; // 从索引2到末尾
// 复杂嵌套访问
nested_value := config["database"]["settings"]["cache"]["ttl"];
// 函数返回值的数组访问
first_item := getData()[0];
user_name := getUsers()[index]["name"];
// 对象方法链式访问
value := obj.getArray().slice(0, 5)[2];
20 TSL SELECT 语法
TSL 语言支持类似 SQL 的查询语法,但有其独特的特性和扩展。主要特点包括:
与标准 SQL 的主要区别
- 语句以
end结束,而非分号 - 字段访问必须使用
[字段名]格式 - 不支持
TOP N,但支持更灵活的DRANGE - 聚集函数名称添加
of后缀(如countof,avgof) - 支持矩阵和数组操作
- 大小写敏感的字段名
基本语法
- 通用语法结构
SELECT/UPDATE/DELETE/INSERT ... END;
- 字段访问方式
- 单表访问:
["字段名"] - 多表访问:
[表序号].["字段名"](表序号从 1 开始) - 整数下标访问:
[0](访问第 0 列)
- 单表访问:
SELECT 语句
select 基本语法
SELECT [选项] [DISTINCT] [DRANGE(范围)]
<选择列表>
FROM <数据源>
[WHERE <条件>]
[GROUP BY <分组表达式>]
[HAVING <分组条件>]
[ORDER BY <排序表达式>]
END;
SELECT 的变体
- SELECT - 返回二维数组(默认)
- SSELECT - 返回一维数组
- VSELECT - 返回单个值
- MSELECT - 返回 Matrix 类型(内存优化)
SELECTOPT 选项
| 选项名 | 值 | 含义 |
|---|---|---|
| SELECT_OPT_SINGLEV | 1 | 返回单个值 |
| SELECT_OPT_SINGLEARRAY | 2 | 返回一维数组 |
| SELECT_OPT_MATRIX | 4 | 返回 Matrix 类型 |
| SELECT_OPT_PACKED | 8 | 行列下标为递增数字 |
| SELECT_OPT_AGGSAMENAME | 32 | 聚集函数保持原字段名 |
选择列表语法
*- 返回所有列["字段名"]- 返回指定列表达式 AS "别名"- 带别名的表达式StartIndex TO EndIndex- 返回指定范围的列
DRANGE 用法
- 范围选择:
DRANGE(0 TO 9)- 返回第 0 到第 9 条记录 - 负数索引:
DRANGE(-10 TO -1)- 返回最后 10 条记录 - 等分选择:
DRANGE(1 OF 10)- 返回 10 等分中的第 1 份
WHERE 子句
WHERE ["字段名"] > 85
WHERE ["英语成绩"] > 85 AND ["数学成绩"] > 90
ORDER BY 子句
ORDER BY ["成绩"] DESC
ORDER BY ["语文成绩"] ASC, ["英语成绩"]/["语文成绩"] DESC
GROUP BY 子句
GROUP BY ["性别"]
GROUP BY ["性别"], groupfunc(["英语成绩"])
HAVING 子句
HAVING CountOf(*) > 1
HAVING AvgOf(["成绩"]) > 80
UPDATE 语句
update 基本语法
UPDATE <表名>
SET ["字段1"] = 值1, ["字段2"] = 值2
[WHERE <条件>]
END;
-- 更新单个字段
UPDATE B SET ["英语成绩"] = 79 WHERE ["学号"] = "03" END;
-- 更新多个字段
UPDATE B SET ["英语成绩"] = 79, ["语文成绩"] = 80 WHERE ["学号"] = "03" END;
-- 基于计算的更新
UPDATE B SET ["英语成绩"] = sqrt(["英语成绩"]) * 10 END;
-- 使用ThisRow更新整行
UPDATE R SET ThisRow = DATA WHERE ["学号"] = DATA["学号"] END;
DELETE 语句
delete 基本语法
DELETE FROM <表名>
[WHERE <条件>]
END;
-- 删除指定记录
DELETE FROM A WHERE ["学号"] = "01" END;
-- 删除所有记录
DELETE FROM A END;
-- 使用ThisRow条件
DELETE FROM R WHERE Sum(ThisRow * ThisRow) = 0 END;
INSERT 语句
insert 基本语法
-- 插入单行(按列顺序)
INSERT INTO <表名> VALUES (值1, 值2, ...);
-- 插入单行(指定字段)
INSERT INTO <表名> INSERTFIELDS(["字段1"], ["字段2"]) VALUES (值1, 值2);
-- 批量插入
INSERT INTO <表名> <数据数组>;
-- 按顺序插入
INSERT INTO A VALUES("06", "路人甲") END;
-- 指定字段插入
INSERT INTO A INSERTFIELDS(["学号"], ["姓名"], ["英语成绩"]) VALUES("06", "路人甲", 80) END;
-- 批量插入
A1 := array(("学号":"07", "姓名":"路人乙"), ("学号":"08", "姓名":"路人丙"));
INSERT INTO A A1 END;
高级功能
JOIN 操作
- JOIN - 内连接
- LEFT JOIN - 左连接
- RIGHT JOIN - 右连接
- FULL JOIN - 全连接
- CROSS JOIN - 笛卡尔积
JOIN 语法
-- 使用ON条件
SELECT * FROM A JOIN B ON [1].["学号"] = [2].["学号"] END;
-- 使用WITH ON优化(推荐)
SELECT * FROM A JOIN B WITH ([1].["学号"] ON [2].["学号"]) END;
-- 多字段JOIN
SELECT * FROM A JOIN B WITH ([1].["学号"], [1].["班级"] ON [2].["学号"], [2].["班级"]) END;
-- 多表JOIN
SELECT [1].*, [2].["英语成绩"], [3].["语文成绩"]
FROM A
JOIN B ON [1].["学号"] = [2].["学号"]
JOIN C ON [1].["学号"] = [3].["学号"]
END;
聚集函数
| 函数 | 说明 |
|---|---|
| AvgOf() | 平均值 |
| SumOf() | 求和 |
| CountOf() | 计数 |
| MaxOf() | 最大值 |
| MinOf() | 最小值 |
嵌套查询
SELECT *,
(SELECT ["成绩"] FROM B WHERE ["学号"] = RefsOf(["学号"], 1) END) AS "成绩"
FROM A END;
特殊关键字
ThisRow
- 访问当前行的完整数据
- 对一维数组查询特别有用
- 多表时使用
ThisRow(表序号)
ThisRowIndex
- 返回当前行的索引
- 即使在 ORDER BY 后仍返回原始位置
- 多表时使用
ThisRowIndex(表序号)
ThisGroup
- 在 GROUP BY 中使用
- 代表当前分组的子结果集
- 只能在 SELECT 的 FROM 子句中使用
ThisOrder
- 获取排序后的位置
- 相同值有相同排序号
- 排序号从 1 开始
RefsOf
- 访问上级结果集
- 语法:
RefsOf(表达式, 上级层数) - 用于嵌套查询中引用外层数据
示例集合
基础查询
-- 简单查询
SELECT * FROM ScoreList END;
-- 条件查询
SELECT * FROM ScoreList WHERE ["英语成绩"] > 85 END;
-- 排序查询
SELECT * FROM ScoreList ORDER BY ["英语成绩"] DESC END;
-- 限制结果
SELECT DRANGE(0 TO 9) * FROM ScoreList ORDER BY ["英语成绩"] DESC END;
计算和转换
-- 添加计算列
SELECT *,
RoundTo((["英语成绩"] + ["语文成绩"] + ["历史成绩"] + ["地理成绩"]) / 4, 2) AS "文科成绩"
FROM ScoreList END;
-- 使用聚集函数
SELECT AvgOf(["英语成绩"]) FROM ScoreList END;
-- 条件聚集
SELECT AvgOf(["英语成绩"]) FROM ScoreList WHERE ["英语成绩"] > 85 END;
分组统计
-- 简单分组
SELECT ["性别"], AvgOf(["成绩"]), CountOf(*)
FROM ScoreList
GROUP BY ["性别"] END;
-- 多字段分组
SELECT ["性别"], ["年级"], AvgOf(["成绩"])
FROM ScoreList
GROUP BY ["性别"], ["年级"] END;
-- 分组筛选
SELECT groupfunc(["英语成绩"]), AvgOf(["英语成绩"]), CountOf(*)
FROM ScoreList
GROUP BY groupfunc(["英语成绩"])
HAVING CountOf(*) > 1 END;
一维数组操作
-- 查询一维数组
R := array(1, 2, 3, 4, 5, 6);
R1 := SELECT ThisRow FROM R WHERE ThisRow > 5 END;
-- 返回一维结果
R2 := SSELECT ThisRow FROM R WHERE ThisRow > 5 END;
-- 更新一维数组
UPDATE R SET ThisRow = ThisRow * 10 END;
复杂查询
-- 多表连接与计算
SELECT
[1].["学号"],
[1].["姓名"],
[2].["英语成绩"],
[3].["数学成绩"],
([2].["英语成绩"] + [3].["数学成绩"]) / 2 AS "平均分"
FROM 学生表
LEFT JOIN 英语成绩表 ON [1].["学号"] = [2].["学号"]
LEFT JOIN 数学成绩表 ON [1].["学号"] = [3].["学号"]
WHERE [1].["班级"] = "一班"
ORDER BY "平均分" DESC
END;
注意事项
- 字段名大小写敏感
- 表序号从 1 开始计数
- 使用 WITH ON 代替 ON 以提高 JOIN 性能
- 聚集函数使用时注意添加 of 后缀
- 空值(NIL)的处理需要特别注意
- UPDATE 可以自动创建新列(针对内存结果集)
性能优化建议
- 使用 WITH ON 进行 JOIN 操作
- 合理使用 DRANGE 限制结果集大小
- 在大数据集上使用 MSELECT 返回 Matrix 类型
- 避免在 WHERE 子句中使用复杂计算
- 适当使用索引和预计算优化查询
📝 语法规则和优先级
运算符优先级(从高到低)
- 成员访问和数组访问:
.[] - 后缀运算符:
++--(后缀) - 前缀运算符:
++--(前缀)、+-(正负号)、.!!not、.!、!(求逆)、`(矩阵转置) - 乘方运算符:
^~:^(矩阵乘方) - 乘除运算符:
*/%moddiv:*(矩阵乘法):\\(矩阵左除) - 加减运算符:
+-|(矩阵列连接)Union(矩阵行连接):|(非完全矩阵列连接) - 连接运算符:
$ - 位移运算符:
shlrolshrror - 比较运算符:
=<><><=>= - 集合运算符:
unionunion2minusintersect - 判断运算符:
is class()in - 位与运算符:
.& - 位异或运算符:
.^ - 位或运算符:
.| - 逻辑与运算符:
.&&and - 逻辑或运算符:
.||or - 三元条件运算符:
? : - 赋值运算符:
:=+=-=*=/=union=union2=minus=intersect=
语法规则说明
自增自减语句规则:
- 前缀自增自减:
++variable;--variable;- 作为独立的increment_statement - 后缀自增自减:
variable++;variable--;- 作为postfix_expression,然后作为expression_statement使用 - 优先级和语义:
- 前缀:先修改变量值,再返回新值
- 后缀:先返回原值,再修改变量值
- 在表达式中使用时,两者的语义不同
语句块规则:
- 单行语句:可以省略
begin end - 多行语句:必须用
begin end包围 end后的分号可有可无
类语法规则:
- 类声明:
type ClassName = class [inheritance] [members] end [;] - 继承语法:
class(BaseClass) - 访问修饰符:影响后续所有成员,直到遇到新的修饰符
- 成员标签:
[tag]必须紧接在成员名称前 - 方法实现:可以在类内或类外实现
- 操作符重载:使用
function operator[symbol]语法,类外实现使用function operator ClassName.[symbol]
Unit 语法规则:
- Unit 声明必须在文件开头
- Unit 名称后的分号不能省略
- 结束标记必须是
end.(点号不能省略) - 一个文件只能包含一个 Unit
- 使用
uses引入单元时,单元名不需要引号
🚀 实际应用示例
使用所有新特性的综合示例
// 使用所有新特性的综合示例
function comprehensive_matrix_processor(input_data);
begin
// 使用解包获取输入
[matrices, sets, config, filters] := input_data;
// 验证配置
if not (config["mode"] in array("matrix", "set", "mixed")) then
raise "Invalid mode: " $ config["mode"] $ " (expected: matrix/set/mixed)";
processed_results := array();
for i := 0 to length(matrices) - 1 do
begin
matrix := matrices[i];
// 使用is class判断对象类型
if matrix is class(Matrix) then
begin
echo "Processing matrix: " $ matrix.name $ " (size: " $ matrix.rows $ "x" $ matrix.cols $ ")";
// 矩阵运算
transposed := `matrix.data; // 矩阵转置(前缀)
inverted := !matrix.data; // 矩阵求逆
squared := matrix.data :^ 2; // 矩阵平方
// 矩阵连接运算
if i < length(matrices) - 1 then
begin
next_matrix := matrices[i + 1];
if next_matrix is class(Matrix) then
begin
// 尝试不同的连接方式
col_concat := matrix.data | next_matrix.data; // 列连接
row_concat := matrix.data Union next_matrix.data; // 行连接
// 矩阵乘法
if matrix.cols = next_matrix.rows then
multiplied := matrix.data :* next_matrix.data;
end;
end;
processed_results[length(processed_results)] := array(
"type": "matrix",
"original": matrix.data,
"transposed": transposed,
"operations": array("transpose", "invert", "power")
);
end
else begin
echo "Skipping non-matrix object at index " $ i;
end;
end;
// 集合运算处理
combined_sets := array();
for j := 0 to length(sets) - 1 do
begin
current_set := sets[j];
// 集合运算
if j = 0 then
combined_sets := current_set
else begin
// 根据配置选择不同的集合运算
operation := config["set_operation"];
if operation = "union" then
combined_sets union= current_set
else if operation = "intersect" then
combined_sets intersect= current_set
else if operation = "minus" then
combined_sets minus= current_set
else
combined_sets union2= current_set;
end;
end;
// 使用函数指针进行回调处理
if "callback" in config then
begin
callback_ptr := config["callback"];
for result in processed_results do
begin
##callback_ptr(result); // 函数指针调用
end;
end;
// 矩阵转置表达式语句
`matrix; // 矩阵转置表达式语句(前缀)
matrix1 :* matrix2; // 矩阵乘法表达式语句
// 自增自减表达式语句
counter++; // 后缀自增表达式语句
working_set.length++; // 对象成员自增表达式语句
return array(
"matrices": processed_results,
"combined_sets": combined_sets,
"total_operations": length(processed_results) + length(sets)
);
end;
🔧 语法解析器使用
生成解析器
tree-sitter generate
运行测试
chmod +x test_tsf.sh
./test_tsf.sh
解析单个文件
tree-sitter parse your_file.tsf
调试语法
tree-sitter parse your_file.tsf --debug
📊 支持的特性总结
✅ 完整支持的特性:
- 🔧 函数定义和调用(参数类型、默认值、重载)
- 🔗 函数指针调用(
##pointer(args)语法) - 📊 灵活的嵌套数组系统(支持表达式、函数调用、元组、键值对混合)
- 📤 解包(destructuring)赋值语法(数组元素自动分配)
- 🔑 关键字语句(echo 输出、raise 异常抛出)
- 🔗 $万能连接符(任意类型自动转换连接)
- 🔍 判断语法(is class 类型检查、in 成员检查)
- 📊 矩阵运算系统(前缀转置、求逆、乘法、连接、乘方等)
- 🔢 集合运算系统(并集、交集、差集及其复合赋值)
- 📝 表达式语句(任何表达式都可以作为独立语句使用)
- 🏗️ 完整的类和对象系统(继承、访问控制、方法重写、操作符重载)
- 📦 Unit 模块系统(接口、实现、初始化、析构)
- ➕ 丰富的运算符集合(算术、逻辑、位运算、三元表达式)
- 🔀 完整的控制流语句(if/else、case、循环、跳转)
- 🔍 特殊查询语法(vselect/select/sselect)
- 🔢 多种数字格式(十进制、科学记数法、十六进制、二进制、八进制)
- 🗨️ 多种注释类型(行注释、两种块注释)
- 📝 数组索引和切片访问(多维数组、嵌套访问、切片操作)
- 🆕 对象创建和成员访问(new 操作符、链式调用、成员操作)
🆕 新增的高级特性:
- 操作符重载:
function operator[symbol]语法,支持类的自定义运算符行为 - 函数指针调用:
##pointer(args)语法,支持动态函数调用 - 矩阵运算:
`转置(前缀)、!求逆、:*乘法、:\\左除、:^乘方、|列连接、Union行连接 - 集合运算:
union并集、intersect交集、minus差集、union2特殊并集 - 复合赋值扩展:
union=、intersect=、minus=、union2=等集合运算复合赋值 - 表达式语句:支持将任何表达式作为独立语句,便于函数调用和副作用操作
这个语法解析器为 TSF 语言提供了完整的语法支持,特别是在数组处理、类型检查、异常处理、字符串连接、矩阵运算、集合运算、操作符重载和函数指针调用方面具有强大的能力。这些特性使得 TSF 语言在科学计算、数据处理和面向对象编程领域更加强大和实用。