#语法概述
GPML使用严格的XML语法(关于什么是XML,请自行谷歌),每个GPML源文件必须是形式良好的XML文档.
你需要按照XML的规则转义需要转义的字符.
GPML从不使用XML标记的属性.
每个标签名都有对应的中文和英文,可在后面速查表查到.
我们约定每个源文件的根元素均为<GPML />
,强制使用UTF-8编码.
本文档是一份参考而非教程,阅读本文档需要您有其他语言的编程基础.
#变量 ##基本数据类型
<int />
整数<long />
无限精度整数<string />
字符串<byte />
字节<float />
浮点数<double />
无限精度小数<bool />
比特,布尔值
###特殊值
-
<true />
真,用于<bool />
. -
<false />
假,用于<bool />
. -
<zero />
数字零,用于<int />
、<long />
、<byte />
、<float />
、<double />
-
<max />
最大值,用于<int />
、<byte />
、<float />
-
<empty />
空字符串,用于<string />
-
<null />
空,独立于类型
###默认初值
<int />
-<zero />
<long />
-<zero />
<string />
-<empty />
<byte />
-<zero />
<float />
-<zero />
<double />
-<zero />
<bool />
-<false />
###有效范围
<int />
- 长度为寄存器位数<float />
- 遵循IEEE 754的规定,长度为寄存器位数
##字面常量
<类型>值</类型>
- 上面的类型是占位符,不是指
<type />
标记 - 任何时候,使用字面常量都需要写明类型
例如一个值为123的整数:
<int>123</int>
再例如一个值为Hello World的字符串:
<string>Hello World</string>
##声明和定义一个变量
<variable>
<type>类型</type>
<name>变量名</name>
<value>初值</value>
</variable>
- 变量名区分大小写,可以使用任何字符,只需要按照XML的规则进行转义(以后不再强调).
- 初值为可选项,是一个右值表达式,不声明初值即使用相应类型的默认初值.
例如声明一个名为a,类型为int,初值为456的变量:
<variable>
<type><int /></type>
<name>a</name>
<value><int>456</int></value>
</variable>
###常量
通过在声明变量时加入<const />
标记,即可表示这个变量为常量,不可更改
例如:
<variable>
<type><int /></type>
<name>a</name>
<value><int>456</int></value>
<const />
</variable>
##引用变量 你可以在任何一个需要右值的地方通过下面的方式引用一个变量:
<variable>变量名</variable>
例如引用一个变量名为a的变量:
<variable>a</variable>
##赋值
<move>
<form>右值表达式</form>
<to>左值</to>
</move>
<form />
和<to />
的类型必须相同,或满足自动类型转换的条件.
例如将a赋值给b:
<move>
<form><variable>a</variable></form>
<to><variable>b</variable></to>
</move>
再例如将字面常量Hello World赋值给a:
<move>
<form><string>Hello World</string></form>
<to><variable>a</variable></to>
</move>
###运算符 有下面五种运算符:
<plus />
- 加,适用于<int />
、<long />
、<byte />
、<float />
、<double />
、<string />
<minus />
- 减,适用于<int />
、<long />
、<byte />
、<float />
、<double />
<multiply />
乘,适用于<int />
、<long />
、<byte />
、<float />
、<double />
、<string />
<except />
除,适用于<int />
、<long />
、<byte />
、<float />
、<double />
<mod />
取余数,适用于<int />
、<long />
、<byte />
你可以使用<calc />
标签进行计算,例如计算1和2的和:
<calc>
<value><int>1</int></value>
<plus />
<value><int>2</int></value>
</calc>
你也可以一次计算两个以上的数,但是他们会按顺序进行计算,而不是按照运算符的优先级计算:
<calc>
<value><int>1</int></value>
<plus />
<value><int>2</int></value>
<multiply />
<value><int>3</int></value>
</calc>
上面的代码计算的是(1+2)*3的值.
你还可以在<move />
标签中对多个<form />
进行计算.
例如计算2*3,将结果赋值到变量a:
<move>
<form><int>2</int></form>
<multiply />
<form><int>3</int></form>
<to><variable>a</variable></to>
</move>
#作用域
下列标记中,将视为一个单独的作用域:<select />
、<while />
、<case />
、<function />
引用变量时,从内层向外层开始查找,直到找到这个标识符.
#流程控制 ##选择语句 ###单选
<select>
<if>布尔表达式</if>
<then>
语句序列A
</then>
<else>
语句序列B
</else>
</select>
- 当布尔表达式为
<true />
时,执行<then />
中的语句序列,执行<else />
中的语句序列. <else />
可省略.
###多选
<select>
<if>右值表达式</if>
<case>
<value>匹配值1</value>
<then>
语句序列1
</then>
</case>
<case>
<value>匹配值2</value>
<then>
语句序列2
</then>
</case>
<else>
语句序列3
</else>
</select>
-
依次执行所有
<value />
与<if />
相等的<case />
中的<then />
中的语句. -
如果没有一个
<case />
被匹配,则执行<else />
中的语句. -
各
<value />
的类型和<if />
必须相同,或满足自动类型转换的条件. -
<value />
可省略,这时的<case />
必被执行. -
单选和多选并不兼容,
<case />
和<then />
不能直接存在于<select />
下.
##循环语句 ###当型循环
<while>
<if>布尔表达式</if>
<then>
语句序列
</then>
</while>
- 执行
<then />
中的语句序列直到<if />
为<false />
. <if />
可省略,这时为死循环.
###计数循环和遍历
<while>
<for>整数表达式或列表对象</for>
<index>计数器/指针名</index>
<then>
语句序列
</then>
</while>
- 如果
<for />
为整数,则执行<then />
中的语句序列<for />
次,<index />
中定义的变量名作为计数器,由0起始. - 如果
<for />
为列表对象类型,则对于其中的每个元素执行<then />
中的语句序列,<index />
中定义的变量名作为循环指针. <index />
可省略.
###跳出循环
<break />
- 该标记可跳出
<while />
循环.
###进入下一次循环
<continue />
- 该标记可跳过
<while />
的剩余部分,进入下一次循环.
#数组 ##声明数组 和声明变量很类似,我们只需要在类型上下文章就行了:
<variable>
<type>
<listof>元素类型</listof>
<size>数组尺寸</size>
</type>
<name>数组名</name>
<value>初值</value>
</variable>
例如声明一个具有10个整数元素的数组a,每个元素的初值均为100:
<variable>
<type>
<listof><int /></listof>
<size><int>10</int></size>
</type>
<name>a</name>
<value><int>100</int></value>
</variable>
这种情况下,每个元素都会被设置为初值,你可以通过下面的方式,为数组的每个元素设定不同的初值:
<variable>
<type>
<listof>元素类型</listof>
<size>数组尺寸</size>
</type>
<name>数组名</name>
<value>
<value>初值1</value>
<value>初值2</value>
<value>初值3</value>
</value>
</variable>
<size />
是整形表达式.
##引用数组元素 你可以这样引用数组的元素
<indexof>
<variable>数组名名</variable>
<index>索引值</index>
</indexof>
- 一个数组的元素范围是0到
<size />
减一.
#函数 ##定义函数
<function>
<name>函数名<name>
<type>返回值类型<type>
<params>
<variable>
<type>参数类型1</type>
<name>参数名1</name>
<value>参数默认值1</value>
</variable>
<variable>
<type>参数类型2</type>
<name>参数名2</name>
<value>参数默认值2</value>
</variable>
</params>
<body>
函数语句序列
<return>返回值</return>
</body>
</function>
<params />
中的<variable />
中的<value />
可省略,这时调用时要求必须提供参数.<type />
可省略,这时不返回值.- 在
<body />
中恰当的位置应该用<return />
来返回值. - 支持函数重载
##调用函数
<call>
<function>函数名</function>
<params>
<variable>参数1</variable>
<variable>参数2</variable>
</params>
</call>
##模板函数
<function>
<name>函数名<name>
<type>返回值类型<type>
<template>模板参数1<template>
<template>模板参数1<template>
<params>
<variable>
<type>参数类型1</type>
<name>参数名1</name>
</variable>
</params>
<body>
函数语句序列
</body>
</function>
- 在整个函数范围内,
<template>模板参数名<template>
即可作为类型名使用.
在参数声明中,还可以直接把<type />
替换成<template />
,这样即可自动接收任意类型的参数,在调用时也不必写明模板参数,例如:
<function>
<name>函数名<name>
<type>返回值类型<type>
<params>
<variable>
<template>模板参数名</template>
<name>参数名</name>
</variable>
</params>
<body>
函数语句序列
</body>
</function>
##调用模板函数
<call>
<function>函数名</function>
<template>模板参数1<template>
<template>模板参数2<template>
<params>
<variable>参数1</variable>
<variable>参数2</variable>
</params>
</call>
- 模板参数是一个类型名,例如
<int />
.
##参数传递方式
默认使用传值方式传递参数,可通过添加<byref />
标记来通过引用方式传递参数,例如:
<function>
<name>函数名<name>
<type>返回值类型<type>
<params>
<variable>
<type>参数类型</type>
<name>参数名</name>
<byref />
</variable>
</params>
<body>
函数语句序列
</body>
</function>
#类 ##定义类
<class>
<name>类名<name>
<public>
公有成员
</public>
<protected>
保护成员
</protected>
<private>
私有成员
</private>
</class>
- 你可以在
<public />
、<protected />
、<private />
中声明成员变量、成员函数. - 构造函数与类名同名.
- 析构函数与类名同名,且仅接受一个
<null />
类型的参数. - 构造函数和析构函数不返回值.
声明成员变量和成员函数时,可以加入<static />
标记使其成为静态成员.
在类的实例中,可使用<this />
引用到当前实例.
##引用类成员 引用成员函数:
<call>
<function>
<class>类名</class>
<name>函数名</name>
</function>
<params>
<variable>参数1</variable>
<variable>参数2</variable>
</params>
</call>
引用成员变量:
<variable>
<class>类名</class>
<name>变量名</name>
</variable>
- 其中
<class> /
可以嵌套.
##声明对象 声明对象和声明一个变量一样:
<variable>
<type><class>类名</class></type>
<name>变量名</name>
</variable>
可以通过<params />
向类的构造函数传递参数:
<variable>
<type><class>类名</class></type>
<name>变量名</name>
<params>
<variable>参数1</variable>
<variable>参数2</variable>
</params>
</variable>
##继承
可以加入<inherit />
标记来生成派生类:
<class>
<name>类名<name>
<inherit>
<public />
<class>基类名</class>
</inherit>
</class>
- 可以加入多个
<inherit />
标记来进行多重继承. - 可以在成员函数中加入
<abstract />
标记来表示这是一个抽象函数,派生类必须实现该函数,这种情况函数的<body />
可以省略. - 可以在成员函数中加入
<virtual />
标记来表示这是一个虚函数.
#编译和执行
编译和解释时,全部代码都被读入编译器/解释器来建立模型,所以标识符在使用前无需声明.
程序执行从一个无参数的main函数开始.
##编译时包含
<include>文件名</include>
- 编译器会确保每个文件只被包含一次.
#标记速查
- int - 整数
- long - 无限精度整数
- string - 字符串
- byte - 字节
- float - 浮点数
- double - 无限精度小数
- bool - 布尔
- true - 真
- false - 假
- zero - 零
- max - 最大
- empty - 空
- null - 无
- variable - 变量
- type - 类型
- name - 名字
- value - 值
- const - 常量
- form - 从
- to - 至
- plus - 加
- minus - 减
- multiply - 乘
- except - 除
- mod - 取余数
- select - 选择
- if - 如果
- then - 则
- else - 否则
- case - 匹配
- while - 循环
- for - 对于
- index - 索引
- break - 跳出
- continue - 继续
- listof - 一个列表
- size - 尺寸
- indexof - 元素
- body - 主体
- return - 返回
- template - 模板
- call - 调用
- byref - 传地址
- class - 类
- inherit - 继承
- public - 公有
- protected - 保护
- private - 私有
- static - 静态
- this - 当前
- inherit - 继承
- abstract - 抽象
- virtual - 虚
- include - 包含