跳转至

Platypus Syntax Specification

以下是 Pipeline 处理器语言定义。随着不同语法的逐步支持,该文档会做不同程度的调整和增删。

标识符与关键字

标识符

标识符用于标识对象,可以用来表示一个变量、函数等,标识符包含关键字

自定义的标识符不能与 Pipeline 数据处理器语言的关键字重复

标识符可以由数字(0-9)、字母(A-Z a-z)、下划线(_) 构成,但首字符不能是数字且区分大小写:

  • _abc
  • abc
  • abc1
  • abc_1_

如果需要以字母开头或在标识符中使用上述字符外需要使用反引号:

  • `1abc`
  • `@some-variable`
  • `这是一个表情包变量👍`

特殊标识符

特殊标识符(_)表示 platypus 脚本触发时的外部原始输入数据,这一参数可能隐式传递给部分函数

在部分函数中,为保持前向兼容,_ 将被视为 message 的别名。

关键字

关键字是具有特殊意义的单词,如 if, elif, else, for, in, break, continue

注释

# 为行注释字符,不支持行内注释

# 这是一行注释
a = 1 # 这是一行注释

"""
这是一个(多行)字符串,替代注释
"""
a = 2

"字符串"
a = 3

内置数据类型

在 Pipeline 数据处理器语言中,变量的值的类型可以动态变化,但每一个值都有其数据类型,其可以是基本类型的其中一种,也可以是复合类型

基本类型

整数(int)类型

整型的类型长度为 64bit,有符号,当前仅支持以十进制的方式编写整数字面量,如 -1, 0, 1, +19

浮点(float)类型

浮点型的类型长度为 64bit,有符号,当前仅支持以十进制的方式编写浮点数字面量,如 -1.00001, 0.0, 1.0, +19.0

布尔(bool)类型

布尔类型字面量仅有 truefalse 两种

字符(str)串类型

字符串字面量可用双引号或单引号,多行字符串可以使用三双引号或三单引号将内容括起来进行编写

  • "hello world"

  • 'hello world'

  • """hello world"""

  • ''' hello world '''

Nil 类型

nil 为一种特殊的数据类型,表示无值,该类型字面量为 nil,当一个变量未赋值就使用时,其值为 nil

复合类型

map 类型与 list 类型与基本类型不同,多个变量可以指向同一个 map 或 list 对象,在赋值时并不会进行 list 或 map 的内存拷贝,而是进行引用

Map 类型

map 类型为 key-value 结构,只有字符串类型才能作为 key,不限制 value 的数据类型

其可通过索引表达式读写 map 中的元素

a = {
  "1": [1, "2", 3, nil],
  "2": 1.1,
  "abc": nil,
  "def": true
}

# 由于 a["1"] 是 list 对象,此时 b 只是引用了 a["1"] 的值
b = a["1"]

"""
此时 a["1"][0] == 1.1
"""
b[0] = 1.1

List 类型

list 类型可以在 list 中存储任意数量、任意类型的值 其可通过索引表达式读写 list 中的元素

1
2
3
a = [1, "2", 3.0, false, nil, {"a": 1}]

a = a[0] # a == 1

运算符

以下为 Platypus 当前支持的运算符,数值越大优先级越高

优先级 符号 结合性 描述
1 = 赋值;命名参数;优先级最低
2 \|\| 逻辑"或"
3 && 逻辑"与"
4 >= 条件"大于等于"
4 > 条件"大于"
4 != 条件"不等于"
4 == 条件"等于"
4 <= 条件"小于等于"
4 < 条件"小于"
5 + 算术"加"
5 - 算术"减"
6 * 算术"乘"
6 / 算术"除"
6 % 算术"取余数"
7 [] 使用 list 下标或 map 的键取值
7 () 可改变运算符优先级;函数调用

表达式

Platypus 使用符号逗号 , 作为表达式分隔符号,如用于调用表达式的参数传递和 map、list 的初始化时的表达式的分隔

调用表达式

以下为一个函数调用,用于取列表元素个数:

len([1, 3, "5"])

二元表达式

赋值表达式属于二元表达式,其有返回值

# 0
2 / 5

# 0.4,计算时将左操作数的类型提升至浮点数
2 / 5.0

# true
1 + 2 * 3 == 7 && 1 <= 2

# b == 3; 
# 由于 `=` 运算符的右结合性, a = (b = 3), a == 3
a = b = 3

List 初始化表达式

[1, true, "1", nil]

Map 初始化表达式

1
2
3
4
{
  "a": 1,
  "b": "2",
}

括号表达式

括号表达式可以改变二元表达式中的操作数运算优先级,但不能改变结合性

1
2
3
# 1 + 2 * 3 == 7

(1 + 2) * 3  # == 9

语句

Platypus 所有的表达式可以视为值语句,当表达式以语句分隔符号 ;\n 结束时,其将被视为一个语句,如以下脚本内容包含四个语句

1
2
3
len("abc")
1
a = 2; a + 2 * 3 % 2

值语句(表达式语句)

表达式后面跟语句分隔符号时可视为值语句,以下为四个合法的语句

1
2
3
a = 1; b = 2;
d = [1, 2]
len(d)

选择语句

Platypus 支持 if/elif/else 语法:

1
2
3
if condition {

}
1
2
3
4
5
if condition {

} else {

}
1
2
3
4
5
6
7
8
9
if condition_1 {

} elif condition_2 {

} ... elif condition_n {

} else {

}

与大多数编程语言相同,根据 if/elif 的条件是否成立,进入对应的语句块中,若都不成立则进入 else 分支。

当前 condition 可以是任意表达式,只要其值为内置数据类型之一,以下为判定条件:

  • 当条件为 int 类型值时,其为 0 则条件为 false,否则为 true

  • 当条件为 float 类型值时,其为 0.0 则条件为 false,否则为 true

  • 当条件为 string 类型值时,其为空字符串 "" 则条件为 false,否则为 true

  • 当条件为 bool 类型值时,条件为当前值

  • 当条件为 nil 类型值时,条件为 false

  • 当条件为 map 类型值时,其长度为 0 则条件为 false,否则为 true

  • 当条件为 list 类型值时,其长度为 0 则条件为 false,否则为 true

循环语句

Platypus 支持 for 语句和 for in 语句

以下为两个只允许在循环语句块中使用的语句:

  • cotinue 语句,不再执行后续语句,继续开始下一次循环
  • break 语句,结束循环

使用 for 语句时可能造成无限循环,应谨慎使用,或尽可能使用 for in 语句替代

1
2
3
for init-expr; condition; loop-expr {

}
1
2
3
for varb_name in map_value/list_value/string_value  {

}

使用示例:

  1. 使用 for 执行 10 次循环
1
2
3
for a = 0; a < 10; a = a + 1 {

}
  1. 使用 for in 遍历 list 的所有元素
1
2
3
4
5
6
7
8
9
b = "2"
for a in ["1", "a" ,"2"] {
  b = b + a
  if b == "21a" {
    break
  }
}

# b == "21a"
  1. 使用 for in 遍历 map 的所有键
1
2
3
4
5
d = 0
map_a = {"a": 1, "b":2}
for x in map_a {
  d = d + map_a[x]
}
  1. 使用 for in 遍历 string 的所有字符
s = ""
for c in "abcdef" {
  if s == "abc" {
    break
  } else {
    continue
  }
  s = s + "a"
}

# s == "abc"