词法¶
源文件与编码¶
Lumos 仅接受 Unicode 源码文件,编码必须为 UTF-8、UTF-16 或 UTF-32,不允许任何无法解析为文本的二进制内容。
所有内容区分大小写,且不允许 BOM;若检测到 BOM 将直接报错。
标识符¶
语法规则¶
标识符由字母、数字和下划线组成:
- 首字符:必须为字母或下划线
[a-zA-Z_] - 后续字符:可为字母、数字或下划线
[a-zA-Z0-9_]* - 保留字:大部分情况下 Lumos 关键字不可作为标识符使用(见 关键字列表)
- 下划线前缀只分配给非公开成员:以单个下划线开头的标识符被约定为私有或内部使用,虽然语法上仍然有效,但建议遵循这一约定以提高代码可读性。
- 同时添加下划线前后缀只分配给私有成员:以单个下划线开头并以单个下划线结尾的标识符被约定为私有成员,虽然语法上仍然有效,但建议遵循这一约定以提高代码可读性。
var i32 count = 0; // ✓ 有效
val name = "Alice"; // ✓ 有效
i32 _private = 42; // ✓ 有效(下划线前缀表示私有/内部)
i32 x123 = 1; // ✓ 有效
i32 123var; // ✗ 无效(以数字开头)
二进制标识符¶
默认标识符仅允许上述 ASCII 字符的子集,若需要使用其它内容作为名称,必须使用 $"..." 的形式,并遵循 b"..." 的字节串转义规则:
val $"变量" = 10; // ✓ Unicode 标识符
val $"π" = 3.14159; // ✓ 特殊符号
val $"😀" = "emoji"; // ✓ 表情符号
val $"var with spaces" = 42; // ✓ 包含空格
val $"\0\x12\x34\x56" = 0; // ✓ 二进制内容
此时使用这些变量和函数时也需要使用 $"..." 的形式:
println($"变量"); // 输出 10
命名约定¶
虽然语法允许多种形式,但建议遵循以下命名约定以提高代码可读性和一致性:
| 类别 | 风格 | 示例 |
|---|---|---|
| 变量/参数 | snake_case |
max_count, user_name, is_valid |
| 函数 | snake_case |
calculate_sum, handle_event, parse_json |
| 类型/结构体 | PascalCase |
Point, Vector, LinkedList |
常量(lit/imv) |
UPPER_CASE |
PI, MAX_SIZE, DEFAULT_TIMEOUT |
空白字符¶
Lumos 认可的空白字符为 \x20(空格)、\x09(制表符)和 \x0A(换行符)。其它任何字符均不被视为空白字符。
行号在遇到换行符(LF)时递增,列号在换行处重置。回车符(CR, \x0D)本身不增加行号,但仅允许作为 CRLF 序列的一部分(即 CR 必须紧跟 LF);在其他位置出现 CR 将引发词法错误。
行首的空白(空格或制表符)被视为缩进。单个行的缩进必须只使用空格或只使用制表符,混用空格和制表符进行缩进会导致词法错误。
运算符¶
对于运算符,Lumos 采用简单且一致的规则:
- 下列字符可作为运算符的一部分:
! % ^ & * - + = | : < > , . ? / ~ - 采用永远最长匹配原则进行运算符识别。
也就是说,遇到 a+-b 时会被解析为单个 +- 运算符,而不是 + 运算符后跟 - 运算符;如果未定义 +-,则会报错。
例如,我们可以用带斜线的标识符为运算符提供实现:
// 我们用 `\mul` 来表示 `*` 运算符
// `\mul_mul` 对应 `**` 运算符
def \mul_mul(int a, int b) -> int {
return pow(a, b);
}
自定义运算符不得超过 4 个字符长度。
相关内容:语法入口见 语法。
字符分类
X非法字符 (默认除 TAB LF 外的 ASCII 控制字符)S空字符 (默认仅空格,不允许 TAB)N换行符 (默认仅 LF,不允许 CR)I标识符 (ASCII 字母数字下划线)P分隔标点 (与邻接的非同类内容不会组合到一起)C连接标点 (与邻接的内容可能组合到一起)E扩展标识符 (ASCII 以外的 Unicode 字符)
一旦遇到非法字符直接报告编译失败,字符串字面量文本也不允许出现非法字符,但可以使用转义序列插入非法字符或从外部导入包含非法字符的文本作为字符串字面量。
| ID | 字符 | 类型 | 说明 |
|---|---|---|---|
| 33 | ! |
P | |
| 34 | " |
C | u16"xxx" 为一个单元 |
| 35 | # |
P | |
| 36 | $ |
C | $"xxx" 为一个单元 |
| 37 | % |
P | |
| 38 | & |
P | |
| 39 | ' |
C | h'ff 为一个单元 |
| 40 | ( |
P | |
| 41 | ) |
P | |
| 42 | * |
P | |
| 43 | + |
P | |
| 44 | , |
P | |
| 45 | - |
P | |
| 46 | . |
P | |
| 47 | / |
P | |
| 58 | : |
P | |
| 59 | ; |
P | |
| 60 | < |
P | |
| 61 | = |
P | |
| 62 | > |
P | |
| 63 | ? |
P | |
| 64 | @ |
P | |
| 91 | [ |
P | |
| 92 | \ |
P | |
| 93 | ] |
P | |
| 94 | ^ |
P | |
| 96 | ` |
C | |
| 123 | { |
P | |
| 124 | \| |
P | |
| 125 | } |
P | |
| 126 | ~ |
P |