表达式与操作符
1 表达式与操作符
一个表达式是由一系列操作符、操作数和特殊字符组成,并在运行时由EGL进行求值运算。操作数可以是常量、标识符或者关键字。EGL可以对以下几种表达式进行运算:
1. 逻辑表达式,可以被赋值为TRUE 或者 FALSE;参见“逻辑表达式”。
2. 数字和文本表达式,可以分别被赋值为数字或字符;参见“表达式类型”。
3. 日期/时间表达式是特殊和复杂的表达式;参见“日期和时间表达式”。
EGL对表达式进行求值运算时会遵循一系列的优先级规则(参见“操作符和优先级规则”)并从左到右(对于具有相同优先级的操作符),但你可以使用括号来强制指定不同的优先级规则。内层括号里的子表达式要在外层括号里的子表达式之前计算,并且所有括号中的表达式要在整个表达式之前先计算。
和数值一样,表达式也有类型。类型是对表达式所能被赋的值的序列集。关于更多的表达式类型的内容,参见“表达式类型”。关于更多的类型相关的内容,参见“类型”和“原始数据类型”。
1.1 特殊字符
在EGL中, 当使用下列功能运算符时可以使用非字母数字字符组:
1. 操作符(参见“操作符和操作数”)
2. 分隔符(参见本章的“分隔符”部分)
3. 类型扩展字符(参见“类型扩展字符”)
分隔符
分隔符用来标记输入的开始和结束。EGL使用下列分隔符:
引号 “”
在EGL中引号通常用来标记文字字符串。
花括号 { }
花括号可以在下列情况中使用:
1.属性值赋值,例如:
Button Button{ text="Button", onClick ::= Button_onClick };
2.记录字段初始值的赋值,例如:
record CustomerRecord {customerNumber=0,customerBalance=0}
customerNumber INT;
customerBalance int;
end
3.初始化变量(通常是数组),例如:
myStringsInit string[] {"Hello", "Goodbye"};
方括号 [ ]
方括号可以在下列情况中使用:
1.表示数组元素的数量:
myBigInts bigint[];
2.列举数组的成员,例如:
myBigInts = [10, 40];
3.数组指针,例如:
myBigInts[2] = 5;
括号()
括号可以在下列情况中使用:
1.函数的参数和返回值,例如:
function testFunction1(myInt INT in) returns(INT)
return(5);
end
function testFunction2()
testFunction1(12);
end
2. 表达式中优先进行求值运算的部分,例如:
newVar INT = (5-2)*4;
3. 表示变量的取值范围(某些类型要求),例如:
newDecimal DECIMAL(10,2);
4. 掩码表示的负数,例如:
result = strLib.formatNumber(myNum,"(*,***,###.##)");
1.2 操作符和优先级
下表按照优先级从高到低的顺序列除了EGL操作符的优先级。有些操作符有多重含义,需要根据上下文来判断。EGL有时用特殊字符去代表类型扩展(参见“类型扩展字符”)和分隔符(参见“分隔符”)。
这个表格不包括赋值运算符(=)和复杂赋值操作符(例如 +=)。关于其他特殊情况,参见“赋值”。
操作符 (以逗号分隔) |
含义 |
. |
成员访问操作符(一个圆点儿)提供了对实体成员访问的功能,例如记录的字段,库的函数,或者变量的属性。允许多级使用。按照从左到右的顺序成员变得更加具体。 |
@ |
@操作符代表一个名字引用属性而非字段。 |
new |
New操作符调用构造函数(一种特殊的用来创建新变量的函数)创建一个引用变量(包含地址而非数值的变量)。除了一些外部类型(EXternalType)的情况,默认情况的构造函数没有任何参数;参见“new 操作数”。 |
[] |
数组访问操作符(方括号)用来分隔指针数值和数组名,或者用来分隔子字符串数值和字符串变量名。a[x] 是一个数组子字符串,b[x:y] 是一个子字符串。 |
+, - |
一元加号(+)和一元减号(-)优先级高于操作数或被括号括起来的表达式,而优先级低于两个表达式之间的操作符。 |
** |
** 是指数操作符,它可以被读作“次方”。例如,c = a**b代表c是a的b次方。第一个操作数(例子中的a)是个浮点类型,但不能是负数。第二个操作数(例子中的b)浮点文本或变量,正数、负数或0. |
*, /, &, |, xor |
乘号(*),整除号(/),和三个按位操作符具有相同的优先级。整除能得到一个小数;例如,7/5得到1.4. 按位操作符 and (&),or(|),和exclusive or(xor)对两个操作数执行按位操作,并返回一个INT类型的数值。操作数应该是下列类型中的一种:HEX(2), HEX(4), HEX(8), INT, 或SMALLINT。操作符通过把HEX或SMALLINT类型的操作数转换成INT类型的操作数作为开始。如果是HEX类型,操作符会在操作数的左边补0直到操作数达到4位为止。 |
% |
%是余数操作符。它对第一个操作数或数字表达式除以第二个操作数或数字表达式以后进行取余操作。例如7%5结果是2. |
+,- |
加号(+)和减号(-)是二进制操作符(要求两个操作数),加号和减号的优先级相同。 |
as |
映射操作符,它指定一个类型(第二个操作数)到第一个操作数。 |
::,?:, + |
EGL 用两个操作符专门表示连接。加号也用来表示连接操作符。关于它们之间的区别,参见“连接操作符”。 |
==, !=, <, >, <=, >=, isa |
进行布尔比较的逻辑操作符具有相同的优先级;每个包含一个或多个这些逻辑操作符的表达式的结果为真(TRUE)或者假(FALSE)。 |
! |
!是否定操作符。EGL 对紧跟在!后边的布尔数值(真true或假false)的逻辑表达式进行取反操作。跟在!后边的表达式必须用括号括起来。 |
is, not, in, like, matches |
这些逻辑操作符用于对具有相同优先级的表达式进行比较;每个包含任一这些操作符的表达式被赋值成真(true)或者假(false)。参见“in 操作符”,“like 操作符”,“matches 操作符”。 |
&&, and |
&&(也读作与(and))代表“两者必须都为真(true)”。如果操作符两边的两个逻辑表达式都为真(true),那么表达式为真(TRUE),否则表达式为假(FALSE)。 |
||, or |
|| (也读作 或(or ))代表“两者其一或者两者都”。如果操作符两边的逻辑表达式都为假(false),那么表达式为假(FALSE),否则表达式为真(TRUE)。 |
例子
如果不注意优先级规则就可能导致意想不到的错误,比如下面的例子:
在第一个例子中,开发人员错误地假设减法的优先级高于乘法:
n NUM(3) = 100 - 98 * 100;
EGL解析得到的实际的算式为100 - (98 * 100), 结果得到一个比 NUM(3)大很多的运算结果。结果得到一个EGL0049E An overflow error occurred when assigning a value of -9,700to n.
在第二个例子中,开发人员想要使得以下表达式为真(true)如果element不是数组myArray的成员:
f (!element in myArray)
相反,“否定(not)” 操作符的优先级高于in 操作符,所以EGL在数组中查找一个false值,但这个行为不是开发人员所希望的。
在以上两个例子中,如果使用括号来强制指定优先级,不仅可以避免这些错误,而且可以使得代码更加容易读懂:
n NUM(3) =