お知らせ

電子会議

ライブラリ

パレット

Delphi FAQ検索

Delphi FAQ一覧

サンプル蔵





FDelphi FAQ
16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル

"式の解釈と計算(2/2)"




 300行を超えたので分割しました。

--------------------------------------------------------------------------
// 式のコンパイル
procedure Expression;
var k: String;
begin
  k := token;
  if (k = '+')   or (k = '-')   or
     (k = 'NOT') or (k = 'LOW') or (k = 'HIGH') then
  begin
    token := NextToken;
    Term;
    if k = '-'    then WorkList.Add('NEG_')
    else
    if k = 'NOT'  then WorkList.Add('NOT_')
    else
    if k = 'LOW'  then WorkList.Add('LOW_')
    else
    if k = 'HIGH' then WorkList.Add('HIGH');
  end
  else Term;

  k := token;
  while (k = '+') or (k = '-') do
  begin
    token := NextToken;
    Term;
    if k = '-' then WorkList.Add('SUB_')
    else
    if k = '+' then WorkList.Add('ADD_');

    k := token;
  end;
end;

// トークンの取得
// 文字列を空白又はタブをデリミタとして分解しトークンリストに入れる
procedure GetToken(s: String; str: TStringList);
var tmp, strbuf: String;
begin
  tmp := '';
  s := AnsiUpperCase(s);

  repeat
    s := Trim(s);

    strbuf := s[1]; tmp := tmp+strbuf; Delete(s, 1, 1);
    if (strbuf = '+') or (strbuf = '-') or (strbuf = '*') or
       (strbuf = '/') or (strbuf = '(') or (strbuf = ')') then
    begin
      if Length(tmp) > 1 then str.Add(Copy(tmp, 1, Length(tmp)-1));
      str.Add(strbuf);
      tmp := '';
    end
    else
    if  (s <> '')                    and
       ((s[1] = ' ') or (s[1] = #9)) then
    begin
      str.Add(tmp);
      tmp := '';
    end;
  until s = '';

  if tmp <> '' then str.Add(tmp);
end;

// 式の計算
function Calculation: Boolean;
var i, temp: Integer; Key: String;
begin
  Result := True;

  for i := 0 to WorkList.Count-1 do
  begin
    Key := WorkList[i];

    if IsNumber('$'+Key) then Push(Key)
    else
    if Key = 'ADD_' then
    begin
      temp := HexToInt(Pop);
      Push(IntToHex(temp+HexToInt(Pop), 4));
    end
    else
    if Key = 'SUB_' then
    begin
      temp := HexToInt(Pop);
      Push(IntToHex(HexToInt(Pop)-temp, 4));
    end
    else
    if Key = 'MUL_' then
    begin
      temp := HexToInt(Pop);
      Push(IntToHex(temp*HexToInt(Pop), 4));
    end
    else
    if Key = 'DIV_' then
    begin
      temp := HexToInt(Pop);
      Push(IntToHex(HexToInt(Pop) div temp, 4));
    end
    else
    if Key = 'NEG_' then
    begin
      temp := HexToInt(Pop);
      Push(IntToHex(-temp, 4));
    end
    else
    if Key = 'NOT_' then
    begin
      temp := HexToInt(Pop);
      Push(IntToHex(not temp, 4));
    end
    else
    if Key = 'LOW_' then
    begin
      temp := HexToInt(Pop);
      Push(IntToHex(temp mod 256, 4));
    end
    else
    if Key = 'HIGH' then
    begin
      temp := HexToInt(Pop);
      Push(IntToHex(temp div 256, 4));
    end
    else
    if Key = 'MOD_' then
    begin
      temp := HexToInt(Pop);
      Push(IntToHex(HexToInt(Pop) mod temp, 4));
    end
    else
    if Key = 'SHR_' then
    begin
      temp := HexToInt(Pop);
      Push(IntToHex(HexToInt(Pop) shr temp, 4));
    end
    else
    if Key = 'SHL_' then
    begin
      temp := HexToInt(Pop);
      Push(IntToHex(HexToInt(Pop) shl temp, 4));
    end
    else
    if Key = 'AND_' then
    begin
      temp := HexToInt(Pop);
      Push(IntToHex(HexToInt(Pop) and temp, 4));
    end
    else
    if Key = 'OR__' then
    begin
      temp := HexToInt(Pop);
      Push(IntToHex(HexToInt(Pop) or temp, 4));
    end
    else
    if Key = 'XOR_' then
    begin
      temp := HexToInt(Pop);
      Push(IntToHex(HexToInt(Pop) xor temp, 4));
    end
    else
    begin
      Result := False;
      Break;
    end;
  end;
end;

// 式の解釈と実行
function Calc(s: String): String;
begin
  Index    := 0;
  StackPtr := 0;
  TokenList.Clear;
  WorkList.Clear;

  GetToken(s, TokenList);
  token := NextToken;
  Expression;
  if Calculation then Result := Pop
  else                Result := calcFault;
end;

end.

Original document by TAK8            氏 ID:(QYR01421)


ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。

Copyright 1996-2002 Delphi Users' Forum