soulner писал(а):Спасибо за ответы.
Лучше парсить. Просто идеологически лучше.
Код: Выделить всё
...
UnNumberChars = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'];
TUnTypeConstantValue = (untnv_IntegerNumber, untnv_FloatNumber, untnv_String, untnv_Boolean);
UnConstValueChars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '-', '+', 'e', 'E'];
...
function CheckNumber(const AKeyWord: WideString; var ATypeValue: TUnTypeConstantValue; var AIntValue: Int64; var AFloatValue: Extended): boolean;
var I: Integer;
Step: Integer;
TempChar: WideChar;
IntString: WideString;
FracString: WideString;
ExponentString: WideString;
FracLength: Integer;
Negative: boolean;
NegativeExponent: boolean;
TmpValue: Extended;
begin
Result:=false;
if AKeyWord[1] = '$' then
begin
AIntValue:=ConvertToHex(AKeyWord);
ATypeValue:=untnv_IntegerNumber;
Result:=true;
Exit;
end;
Step:=0;
IntString:='0';
FracString:='0';
ExponentString:='0';
Negative:=false;
NegativeExponent:=false;
FracLength:=0;
for I:=1 to Length(AKeyWord) do
begin
TempChar:=AKeyWord[I];
Case Step of
0: begin
case TempChar of
'-': Negative:=true;
'+': ;
'.': begin
FracString:='';
Step:=2;
end;
else begin if TempChar in UnNumberChars then
begin
IntString:=TempChar;
Step:=1;
end
else // Неправильное число
Exit;
end;
end;
end;
1: begin // Набираем целую часть
if TempChar in UnNumberChars then
IntString:=IntString+TempChar
else
begin
case TempChar of
'.': begin
FracString:='';
Step:=2;
end;
'E', 'e': Step:=3;
else // Неправильное число
Exit;
end;
end;
end;
2: begin // Набираем дробную часть
if TempChar in UnNumberChars then
begin
FracString:=FracString+TempChar;
FracLength:=FracLength+1;
end
else
begin
case TempChar of
'E', 'e': Step:=3;
else // Неправильное число
Exit;
end;
end;
end;
3: begin // Набираем степень KeyWord: TypeKeyWord;
case TempChar of
'-': NegativeExponent:=true;
'+': ;
else begin if TempChar in UnNumberChars then
begin
ExponentString:=TempChar;
Step:=4;
end
else // Неправильное число
Exit;
end;
end;
end;
4: begin
if TempChar in UnNumberChars then
ExponentString:=ExponentString+TempChar
else // Неправильное число
Exit;
end;
end;
end;
AIntValue:=StrToInt(IntString);
AFloatValue:=StrToFloat(FracString)/Power(10, FracLength);
TmpValue:=StrToInt(ExponentString);
if TmpValue <> 0 then
begin
if NegativeExponent then
TmpValue:=power(10, - TmpValue)
else
TmpValue:=power(10, TmpValue);
TmpValue:=(AIntValue+AFloatValue)*TmpValue;
end
else
TmpValue:=(AIntValue+AFloatValue);
if Negative then
TmpValue:=-TmpValue;
if frac(TmpValue) <> 0 then
begin
ATypeValue:=untnv_FloatNumber;
AFloatValue:=TmpValue;
end
else
begin
ATypeValue:=untnv_IntegerNumber;
AIntValue:=trunc(TmpValue);
end;
Result:=true;
end;
function ConvertToHex(const AText: WideString): Int64;
var I, Q: Integer;
begin
Result:=0;
Q:=0;
for I:=Length(AText) downto 1 do
begin
case UpperCase(AText[I])[1] of
'0': Result:=Result;
'1': Result:=Result+Trunc(Power(16, Q))*1;
'2': Result:=Result+Trunc(Power(16, Q))*2;
'3': Result:=Result+Trunc(Power(16, Q))*3;
'4': Result:=Result+Trunc(Power(16, Q))*4;
'5': Result:=Result+Trunc(Power(16, Q))*5;
'6': Result:=Result+Trunc(Power(16, Q))*6;
'7': Result:=Result+Trunc(Power(16, Q))*7;
'8': Result:=Result+Trunc(Power(16, Q))*8;
'9': Result:=Result+Trunc(Power(16, Q))*9;
'A': Result:=Result+Trunc(Power(16, Q))*10;
'B': Result:=Result+Trunc(Power(16, Q))*11;
'C': Result:=Result+Trunc(Power(16, Q))*12;
'D': Result:=Result+Trunc(Power(16, Q))*13;
'E': Result:=Result+Trunc(Power(16, Q))*14;
'F': Result:=Result+Trunc(Power(16, Q))*15;
'$': begin
if I = 1 then
Exit
else
raise Exception.CreateFmt(Err_ConvertHex, [AText]);
end;
else raise Exception.CreateFmt(Err_ConvertHex, [AText]);
end;
Inc(Q);
end;
end;