第8章
语言定义
air语言是C语法系的编程语言,提供面向对象、函数式、模板等高级语言功能。
air语言是C语法系的编程语言,提供面向对象、函数式、模板等高级语言功能。
语法使用非严格的EBNF语法描述。
文件单元
FileUnit = PkgDef (ImportDef) Decl*
包定义
PkgDef = package ID (.ID)*
依赖导入(可选)
ImportDef = 'import' STRING as ID; |'{' (STRING as ID; )* '}'
声明定义
Decl = ScopeDecl | VarDecl | FuncDecl | EnumDecl | StructDecl | UnionDecl | InterfaceDecl | ClassDecl | EntrustDecl | ~
表达式
Exp = BaseExp | DotExp | UnaryExp | BinaryExp | TernaryExp | NewExp | PriorityExp
基础表达式
BaseExp = IDExp | ConstExp | CallExp | ArrarExp | ThisExp | SuperExp
IDExp = ID
ConstExp = c
CallExp = ID '(' ArgList')'
ArrarExp = ID '[' Exp ']'
ThisExp = 'this'
SuperExp = 'super'
成员访问表达式
DotExp = BaseExp ( '.' BaseExp)* //BaseExp不得是ConstExp
一元表达式
UnaryExp = UnaryOP BaseExp
UnaryOP = '-' | '+' | '--' | '++' | '~' | '!'
二元表达式
BinaryExp = Exp BinaryOP Exp
BinaryOP = '+' | '-' | '*' | '/' | '%' |
'&' | '|' | '&&' | '||' |
'<<' | '>>' | '>>>' |
'<' | '>' | '<=' | '>=' |
'==' | '!=' | '=' |
三元表达式
TernaryExp = Exp '?' Exp ':' Exp
括号表达式
PriorityExp = '(' Exp ')'
作用域声明
ScopeDecl = ( 'public' | 'protected' | 'private' ) ':'
变量声明
VarDecl = Scope Type 'id' [=initExp] ';'
Scope = ['public' | 'protected' | 'private'| 'extern' | 'static']
Type = ['const' ] 'id'( '.' 'id')*
代理变量
Scope Type 'id''(' [ arglist] ')' 'delegate' ';'
闭包变量
Scope Type 'id''(' [ arglist] ')' 'closure' ';'
函数申明
VarDecl = Scope Type 'id''(' [ arglist] ')'[@override] [@cfun] [const] [final] (';' | funbody )
arglist = argitem (',' argitem)*
argitem = type ['id']
funbody = BlkState
BlkState = '{' [Statement] '}'
Statement = ( BlkState | ExpState | IfState | ElseifState |
ElseState | SwitchState | ForState | DoState |
WhileState | GotoState | BreakState | ContinueState |
ReturnState )*
TypeDecl = EnumDecl | StructDecl | UnionDecl |EntrustDecl
FuncDecl = Type 'id''(' [ arglist] ')' '=' Serial
Serial = 'u32'
枚举声明
EnumDecl = 'enum' id [: BaseType]'{' EnumItem* '}'
BaseType = 基本整数类型
EnumItem = 'id'[=initExp] ','每一个文件都必须定义一个作用域名,其他内容在此作用域定义。
生成的声明符号都在该作用域内,只能通过该作用域才能访问代码文件中声明的符号内容。
package pkg.pkg2;
Import file=“dir/file.ext”;
Import file2=“dir/file2.ext”;
或者
Import{
file=“dir/file.ext” ;
file2=“dir/file2.ext”;
}
enum name : int32{
item=0,
item2=23,
…
}
Struct name{
Int32 i32;
Union{
Int32 s32;
Flt32 f32;
}
}
Union name{
Int32 s32;
Flt32 f32;
Struct{…}
}
Interface IFather{
void eat(int32 arg);
}
Interface IFather2{
void say(int32 arg);
}
Interface IChild :[ IFather,IFather2 ]{
void walk(int32 arg);
}
Class Parent {
Private:
Int32 mI32;
Public Flt32 mF32;
Public:
Void print(){}
Protected void toString(){}
Virtual void vfun()=0;
}
Class child: Parent :[ IChild ]{
void eat(int32 arg) @override{}
void say(int32 arg) @override{}
void walk(int32 arg) @override{}
void vfun()@override{}
}airlang 的关键字分为两种:普通关键字,宏关键字。 两者差别不大,但是宏关键字有特殊的标记作用,一般用于注解一些信息。
| 关键字 | 注解 |
|---|---|
| @file | 代码中获取文件的名称字符串 |
| @line | 代码中获取代码所作行号数字 |
| @func | 代码中获取函数声明字符串 |
| @debug | 用于标记只在debug标志下启用的代码 |
| @NotNulptr | 用于标记需要检查函数的指针参数非空 |
| @override | 标记非静态成员函数是重写父类的函数 |
| 固定位宽类型关键字 | 注解 | 位宽(bit) |
|---|---|---|
| void | 空,一般用于表示无返回值 | 0 |
| bool | 布尔类型 | 8 |
| flt32 | 32位单精度浮点 | 32 |
| flt64 | 64位双精度浮点 | 32 |
| int8 | 8位有符号整数 | 8 |
| int16 | 8位有符号整数 | 16 |
| int32 | 8位有符号整数 | 32 |
| int64 | 8位有符号整数 | 64 |
| uint8 | 8位无符号整数 | 8 |
| uint16 | 16位无符号整数 | 16 |
| uint32 | 32位无符号整数 | 32 |
| uint64 | 64位无符号整数 | 64 |
| char | 字符 | 8 |
可变位宽类型的位宽由编译的目标CPU架构有关。
| 可变位宽类型关键字 | 注解 | CPU32 | CPU64 |
|---|---|---|---|
| sint | 有符号整数 | 32 | 64 |
| uint | 无符号整数 | 32 | 64 |
| uintptr | 指针 | 32 | 64 |
| cstring | 字符串指针 | 32 | 64 |
| 修饰关键字 | 注解 |
|---|---|
| static | 静态 |
| public | 完全公开的 |
| protected | 对部分成员公开的 |
| private | 私有的 成员 |
| const | 常量化,只读 |
| friend | 友元定义 |
| 分支关键字 | 注解 |
|---|---|
| if | 比较分支 |
| elsif | 次比较分支 |
| else | 比较默认分支 |
| for | 循环 |
| foreach | 循环 |
| while | 循环 |
| do | 循环 |
| break | 跳出循环 |
| continue | 继续下一轮循环 |
| goto | 跳转到标签 |
| return | 函数返回 |
| 类型定义关键字 | 注解 |
|---|---|
| enum | 枚举 |
| struct | 结构体 |
| union | 联合体 |
| interface | 接口 |
| class | 类 |
| entrust | 委托指针 |
| 其他关键字 | 注解 |
|---|---|
| false | |
| true | |
| nullptr | |
| this | |
| super |
成员访问操作符的优先级最高。
| 成员访问操作符 | 优先级 | 注解 |
|---|---|---|
| . | 0 | 成员访问 |
| .? | 0 | 带null检查的成员访问 |
一元操作符优先级一致,主要查看其声明的先后顺序。
| 一元操作符 | 优先级 | 注解 |
|---|---|---|
| ~ | -10 | 按位取反 |
| ! | -10 | 逻辑取反 |
| - | -10 | 符号取反 |
| + | -10 | 取绝对值 |
| ++ | -10 | 自增 |
| -- | -10 | 自减 |
在语法解析表达式中,二元表达式最复杂的。
| 二元操作符 | 优先级 | 注解 |
|---|---|---|
| * | -20 | 乘运算操作符 |
| / | -20 | 除运算操作符 |
| % | -20 | 模运算操作符 |
| + | -30 | 加运算操作符 |
| - | -30 | 减运算操作符 |
| << | -40 | 左移操作符 |
| >> | -40 | 逻辑右移操作符 |
| >>> | -40 | 算术右移操作符 |
| < | -50 | 小于操作符 |
| <= | -50 | 小于等于操作符 |
| > | -50 | 大于于操作符 |
| >= | -50 | 大于等于操作符 |
| == | -60 | 等于操作符 |
| != | -60 | 不等于操作符 |
| & | -70 | 位与操作符 |
| ^ | -71 | 位异或操作符 |
| | | -72 | 位或操作符 |
| && | -80 | 逻辑与操作符 |
| || | -81 | 逻辑或操作符 |
三元操作符主要用于比较赋值、简单的比较分支操作。
| 三元操作符 | 优先级 | 注解 |
|---|---|---|
| ? : | -90 |
赋值类操作符的优先级一致,优先级最低。
| 赋值操作符 | 优先级 | 注解 |
|---|---|---|
| = | -100 | 赋值操作符 |
| *= | -100 | 乘运算复合赋值操作符 |
| /= | -100 | 除运算复合赋值操作符 |
| %= | -100 | 模运算复合赋值操作符 |
| += | -100 | 加运算复合赋值操作符 |
| -= | -100 | 减运算复合赋值操作符 |
| &= | -100 | 位与运算复合赋值操作符 |
| = | -100 | 位或运算复合赋值操作符 |
| ^= | -100 | 位异或运算复合赋值操作符 |
| ~= | -100 | 位取反运算复合赋值操作符 |
| <<= | -100 | 左移运算复合赋值操作符 |
| >>= | -100 | 逻辑右移运算复合赋值操作符 |
| >>>= | -100 | 算术右移运算复合赋值操作符 |
括号表达式中的括号操作符,用于提升表达式的优先级,在算符优先解析算法,该系列是作为基本表达式进行解析的。
| 括号操作符 | 优先级 | 注解 |
|---|---|---|
| () | -10 | 括号操作符 |
| [] | -10 | 数组下标 |
| cast | -10 | 静态类型转换 |
| dyn_cast | -10 | 动态类型转换 |
| () | -10 | 函数调用 |
| 固定位宽类型 | 注解 | 位宽(bit) |
|---|---|---|
| void | 空,一般用于表示无返回值 | — |
| bool | 布尔类型 | 8 |
| flt32 | 32位单精度浮点 | 32 |
| flt64 | 64位双精度浮点 | 32 |
| int8 | 8位有符号整数 | 8 |
| int16 | 8位有符号整数 | 16 |
| int32 | 8位有符号整数 | 32 |
| int64 | 8位有符号整数 | 64 |
| uint8 | 8位无符号整数 | 8 |
| uint16 | 16位无符号整数 | 16 |
| uint32 | 32位无符号整数 | 32 |
| uint64 | 64位无符号整数 | 64 |
| char | 字符 | 8 |
可变位宽类型的位宽由编译的目标CPU架构有关。
| 可变位宽类型 | 注解 | CPU32 | CPU64 |
|---|---|---|---|
| sint | 有符号整数 | 32 | 64 |
| uint | 无符号整数 | 32 | 64 |
| uintptr | 指针 | 32 | 64 |
| cstring | 字符串指针 | 32 | 64 |
枚举定义只能是定义整数类的值,其占用的字节数、有无符号性,通过基类标识指定。
如下所示:
enum Color:uint32{
Red,
Black,
}结构体在airlang中是值类型,不会进入GC系统,除通过API分配独立的堆内存。
一般用于构成类中的共同属性。
struct Vec2{
int32 x;
int32 y;
}
struct Vec3 :Vec2{
int32 z;
}union Int32{
int32 i32;
struct{
int8 [4] v4;
}
}interface IEvent{
void eat();
}class Parent{
int32 i32;
void doing(){}
}
class Child :Parent <IEvent>{
int64 i64;
void eat()@override{}
}entrust Func = void (int32,int64)@clang;