fcEvaluator.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:3k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. unit fcEvaluator;
  2. interface
  3. uses Classes, SysUtils, fcCommon;
  4. type
  5.   TOperator = (opMultiply, opDivide, opAdd, opSubtract);
  6.   TOperators = set of TOperator;
  7.   TfcEvaluator = class
  8.   protected
  9.     class function GetOperands(s: string; Operators: TOperators;
  10.       var LOperand, ROperand: string; var FoundOp: TOperator): Boolean;
  11.     class procedure ValidateString(s: String);
  12.     class procedure FixString(var s: String);
  13.   public
  14.     class function Evaluate(s: string): Integer;
  15.   end;
  16. const
  17.   OPERATORSCHAR: array[TOperator] of Char = ('*', '/', '+', '-');
  18. implementation
  19. class function TfcEvaluator.GetOperands(s: string; Operators: TOperators;
  20.   var LOperand, ROperand: string; var FoundOp: TOperator): Boolean;
  21. var OpIndex, CurOpIndex: Integer;
  22.     CurOp: TOperator;
  23. begin
  24.   OpIndex := -1;
  25.   for CurOp := Low(TOperator) to High(TOperator) do
  26.     if (CurOp in Operators) then
  27.     begin
  28.       CurOpIndex := fcFindToken(s, ' ', OPERATORSCHAR[CurOp]);
  29.       if (CurOpIndex <> -1) and ((OpIndex = -1) or (CurOpIndex < OpIndex)) then
  30.       begin
  31.         OpIndex := CurOpIndex;
  32.         FoundOp := CurOp;
  33.       end;
  34.     end;
  35.   if OpIndex = -1 then
  36.   begin
  37.     result := False;
  38.     Exit;
  39.   end;
  40.   LOperand := fcGetToken(s, ' ', OpIndex - 1);
  41.   ROperand := fcGetToken(s, ' ', OpIndex + 1);
  42.   result := True;
  43. end;
  44. class procedure TfcEvaluator.ValidateString(s: String);
  45. var i: Integer;
  46. begin
  47.   for i := 1 to Length(s) do
  48.     if (not (s[i] in ['+', '-', '*', '/', ',', ' '])) and (not (ord(s[i]) in [48..57])) then
  49.       raise EInvalidOperation.Create('Only alpha characters "+", "-", "x", and "/" are allowed.');
  50. end;
  51. class procedure TfcEvaluator.FixString(var s: String);
  52. var CurOp: TOperator;
  53. begin
  54.   for CurOp := Low(TOperator) to High(TOperator) do
  55.     s := fcReplace(s, OPERATORSCHAR[CurOp], ' ' + OPERATORSCHAR[CurOp] + ' ');
  56.   while Pos('  ', s) > 0 do
  57.     s := fcReplace(s, '  ', ' ');
  58. end;
  59. class function TfcEvaluator.Evaluate(s: string): Integer;
  60. var LOperand, ROperand: string;
  61.     IntLOperand, IntROperand: Integer;
  62.     FoundOp: TOperator;
  63.     CurResult: Integer;
  64. begin
  65.   ValidateString(s);
  66.   FixString(s);
  67.   CurResult := -1;
  68.   while GetOperands(s, [opMultiply, opDivide], LOperand, ROperand, FoundOp) or
  69.         GetOperands(s, [opAdd, opSubtract], LOperand, ROperand, FoundOp) do
  70.   begin
  71.     IntLOperand := StrtoInt(LOperand);
  72.     IntROperand := StrtoInt(ROperand);
  73.     case FoundOp of
  74.       opMultiply: CurResult := IntLOperand * IntROperand;
  75.       opDivide: if IntROperand <> 0 then CurResult := IntLOperand div IntROperand
  76.                 else raise EInvalidOperation.Create('Divide By Zero Error');
  77.       opAdd: CurResult := IntLOperand + IntROperand;
  78.       opSubtract: CurResult := IntLOperand - IntROperand;
  79.     end;
  80.     s := fcReplace(s, LOperand + ' ' + OPERATORSCHAR[FoundOp] + ' ' + ROperand, InttoStr(CurResult));
  81.   end;
  82.   result := StrToInt(s);
  83. end;
  84. end.