function TBdsProc.BdsSs(var abds: String): ValKind;
var
c: Char;
lpp: TPushPop;
begin
lpp := TPushPop.Create;//建立数据计算对象
while abds< >'' do
begin
c := abds[1];
if IsCalcFh(c) then//是否运算符
begin
lpp.PushFh(c);//保存运算符
abds := CopyRight(abds,2);
end
else
begin
if c=')' then
begin
Dec(Fghpd);//括号匹配
abds := CopyRight(abds,2);
if Fghpd < 0 then
Raise Exception.Create('括号不配对');
Result := lpp.CalcValue;
//返回括号中的子项值,进行下一步计算
lpp.Free;
Exit;
end
else
begin
if c='(' then
Inc(Fghpd);//做括号层数标识
lpp.PushValue(BdsYz(abds));//取下一项的值。
end;
end;
end;
if Fghpd< >0 then
Raise Exception.Create('括号不配对');
Result := lpp.CalcValue;//返回最终运算值
lpp.Free;
end;
function TBdsProc.BdsYZ(var abds: String): ValKind;
begin
if abds< >'' then
begin
if abds[1]='(' then
begin
abds := CopyRight(abds,2);
Result := BdsSs(abds);//递归调用,求括号中的值
end
else
Result := BdsItm(abds);{读一个数据项,
如果包括函数定义,可以在该方法中定义接口或连接}
end;
end;
若表达式要支持函数功能,只要定义系统支持的函数,
在取行表达式因子BdsItm中加入连接函数定义即可,如下:
…..
else if (c< ='Z') and (c >='A') then
begin
bhs := 取出函数名及参数
Result := … //调用函数处理 (函数定义)
abds := 下一项
end
….
< 2 > 数据计算:主要包PushValue,PushFh,
Calccur分别完成存入数、符号、中间计算
procedure TPUSHPOP.PushValue(avalue: CDIKind);
begin
if fisfh=True then
Raise Exception.Create('缺少运算符');
if fisnot then//进行非运算
begin
if avalue.id then
Raise Exception.Create('浮点数不能做非运算');
avalue.ival := not avalue.ival;
fisnot := False;
end;
if IsLgFh(ffh[flevel]) then//运行逻辑运算
begin
value[flevel] := Calclg(value[flevel],
avalue,ffh[flevel]);
//与当前值做逻辑运算
end
else
begin
Inc(flevel);//存数位置指针加1
value[flevel] := avalue;//存入值
if flevel >2 then//数据个数达到4,进行中间运算
Calccur;
end;
fisfh := True;//输入符号可见
end;
procedure TPUSHPOP.PushFh(afh: Char);
begin
if (fisfh=false) then//非运算是一级
begin
if (afh='!') and (not fisnot) then//标识非运算
begin
fisnot := True;
Exit;
end
else
Raise Exception.Create('运算符重复');
End
Else
begin
ffh[flevel] := afh;//存入运算符
fisfh := False; 输入值可见
end;
end;
procedure TPUSHPOP.Calccur;
begin
if IsCcFh(ffh[1]) then//二级运算符
begin
value[1] := Calcsj(value[1],value[2],ffh[1]);
//计算2和3项的值
ffh[1] := ffh[2];//后序运符和值前移
value[2] := value[3];
end
else//一级运算符
begin
value[0] := Calcsj(value[0],value[1],ffh[0]);
//计算1和2项的值
value[1] := value[2];{ 后序运符和值前移,
2和3项的值不计算是为了保持第一个运算符为一级运算符}
value[2] := value[3];
ffh[0] := ffh[1];
ffh[1] := ffh[2];
end;
Dec(flevel);//存数位置指针减1
end;