⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unit3.pas

📁 演示表达式处理过程的源码
💻 PAS
字号:
unit Unit3;
interface
uses unit2, SysUtils;
  {
     special: 0-10;
         '#'=1(结束、开始符号)
         出错=2
     numbers: 11-20;
         整数数字=11
         小数数字=12
     operators: 21-60;
         '+'=21
         '-'=22
         '*'=23
         '/'=24
         '^'=25
         '!'=26(负号)
         '('=27
         ')'=28

         '>'=31
         '>='=32
         '<'=33
         '<='=34
         '='=35
         '!='=36

         'and'=41
         'or'=42
         'not'=43

         其它=51~60
     functions: 61-100;
     preserved: 101-200;
  }
  const
    bigger=1;
    lesser=3;
    equal=2;
    error=10;
  type
    Relations=Record
        a, b, c: integer;
        //a: 第一操作符号; b: 第二操作符号; c: 大小关系;
    end;
    Expression=Class
        optr_s, opnd_s: stack;
        e_string, result: string;
        e_length: integer;
        e_ptr: integer;
        last_word: integer; //修正单词衔接关系
        word_index: integer;
        opnds: opnd_table;
        optrs: optr_table;
        priors: array[1..100, 1..100]of integer;
        error_code: integer;
        error_string: string;
        show_state, show_a: integer; //为了显示操作过程
        function compare(a, b: integer): integer;
        procedure Init_machine;
        procedure Set_string(s: string);
        procedure count_expression(var s: string);
        procedure show_prepare;
        procedure show_count(var s: string); //显示操作过程
        function read_word: integer;
        procedure deal_meaning;
    end;
implementation
procedure expression.Init_machine;
var
     i, j: integer;
begin
     optr_s:=stack.Create;
     optr_s.init;
     opnd_s:=stack.Create;
     opnd_s.init;
     opnds:=opnd_table.Create;
     opnds.init_table;
     optrs.init;
     word_index:=0;
     e_ptr:=0;
     error_code:=0; // error=0 无错
     last_word:=1; //开始
     // some values
     for i:=1 to 100 do begin
         for j:=1 to 100 do begin
             priors[i, j]:=error;
         end;
     end;
     priors[1, 1]:=equal;
     for i:=2 to 100 do begin
         priors[1, i]:=lesser;
         priors[i, 1]:=bigger;
     end;
     for i:=2 to 100 do begin
         priors[27, i]:=bigger;
         priors[i, 27]:=bigger;
         priors[28, i]:=lesser;
     end;
     priors[28, 27]:=equal;
     for i:=21 to 22 do begin
         for j:=21 to 24 do begin
             priors[i, j]:=lesser;
         end;
     end;
     for i:=23 to 24 do begin
         for j:=21 to 22 do begin
             priors[i, j]:=bigger;
         end;
     end;
     for i:=23 to 24 do begin
         for j:=23 to 24 do begin
             priors[i, j]:=lesser;
         end;
     end;
     for i:=21 to 25 do begin
         priors[26, i]:=bigger;
         priors[i, 26]:=lesser;
     end;
    //
end;

procedure expression.Set_string(s: string);
begin
     e_string:=s;
     e_length:=length(s);
end;

function expression.compare(a, b:integer): integer;
var
     x: integer;
begin
     x:=priors[a, b];
     compare:=x;
end;

procedure expression.count_expression(var s: string);
var
   a, x: integer; //x无真实用处
begin
     optr_s.push(1); //开始符号
     a:=read_word;
     while not((a=1)and(optr_s.gettop=1)) do begin
        if (a>10) and (a<=20) then begin
           opnd_s.push(word_index);
           a:=read_word;
        end else begin
           case compare(a, optr_s.gettop) of
                bigger: begin
                    optr_s.push(a);
                    a:=read_word;
                end;
                lesser: begin
                    deal_meaning;
                    //这里将弹出一个或几个操作数
                    //及一个(或几个)操作符号
                    if error_code<>0 then begin
                    //语义出错
                       s:='#'+inttostr(error_code)+':'+error_string;
                       exit;
                    end;
                end;
                equal: begin
                    x:=optr_s.pop;
                    a:=read_word;
                end;
                error: begin
                    //语法出错
                    s:='#'+inttostr(error_code)+':'+error_string;
                    exit;
                end;
           end;
       end;
     end;
     s:=opnds.get_value(opnd_s.pop);
end;

procedure expression.show_prepare;
begin
     show_state:=16;
end;
procedure expression.show_count(var s: string);
var
   x: integer; //x无真实用处
begin
  case show_state of
  16: begin
     show_state:=17;
     show_a:=1;
     s:='88';
  end;
  17: begin
     show_state:=18;
     s:='87';
  end;
  18: begin
     optr_s.push(1); //开始符号
     s:='91';     //开始
     show_state:=1;
  end;
  1: begin
     show_a:=read_word;
     show_state:=2;
     s:='98';
  end;
  4: begin
     s:='99'; //结束
     exit;
  end;
  3: begin
     show_a:=read_word;
     show_state:=2;
     s:='98';  //比较
  end;
  11: begin
     opnd_s.push(word_index);
     show_state:=3;
     s:='92';  //读入
  end;
  12: begin
     optr_s.push(show_a);
     show_state:=3;
     s:='92';  //读入
  end;
  13: begin
     deal_meaning;
     show_state:=2;
     s:='97';  //继续比较
  end;
  14: begin
     x:=optr_s.pop;
     show_state:=3;
     s:='92';  //读入
  end;
  15: begin
     case compare(show_a, optr_s.gettop) of
          bigger: begin
              show_state:=12;
              s:='94'; //bigger
          end;
          lesser: begin
              show_state:=13;
              s:='95'; //lesser
          end;
          equal: begin
              show_state:=14;
              s:='96'; //equal
          end;
          error: begin
              //语法出错
              s:=inttostr(error_code)+':'+error_string;
              exit;
          end;
     end;
  end;
  2: begin
     if not((show_a=1)and(optr_s.gettop=1)) then begin
        if (show_a>10) and (show_a<=20) then begin
           show_state:=11;
           s:='93'; //操作数
        end else begin
           show_state:=15;
           s:='90'; //操作符号
       end;
     end else begin
       s:='89';
       show_state:=4;
     end;
  end;
  end;
end;


procedure expression.deal_meaning;
var
    a, b, x: integer;
    c: double;
begin
    x:=optr_s.pop;
    case x of
    21: begin
        a:=opnd_s.pop;
        b:=opnd_s.pop;
        c:=strtofloat(opnds.get_value(a))+strtofloat(opnds.get_value(b));
    end;
    22: begin
        a:=opnd_s.pop;
        b:=opnd_s.pop;
        c:=strtofloat(opnds.get_value(b))-strtofloat(opnds.get_value(a));
    end;
    23: begin
        a:=opnd_s.pop;
        b:=opnd_s.pop;
        c:=strtofloat(opnds.get_value(a))*strtofloat(opnds.get_value(b));
    end;
    24: begin
        a:=opnd_s.pop;
        b:=opnd_s.pop;
        if strtofloat(opnds.get_value(a))<>0 then begin
           c:=strtofloat(opnds.get_value(b))/strtofloat(opnds.get_value(a));
        end else begin
           c:=0;
        end;
    end;
    26: begin
        a:=opnd_s.pop;
        c:=-strtofloat(opnds.get_value(a));
    end;
    else begin
        error_code:=303;
        error_string:='Invalid operator.';
        exit;
    end;
    end;
    word_index:=word_index+1;
    opnds.add(word_index, 12, floattostr(c));
    opnd_s.push(word_index);
    //result:='********************';
end;

function expression.read_word: integer;
var
   a1, a2: string;
   state: integer;
   the_word: integer;
begin
     state:=0;
     a2:='';
     the_word:=1;
     if e_ptr>=e_length then begin
        read_word:=1; //结束符号
        exit;
     end;
     while (state<>100)and(e_ptr<=e_length) do begin
        e_ptr:=e_ptr+1;
        if e_ptr>e_length then begin
           a1:='#';
        end else begin
           a1:=copy(e_string, e_ptr, 1);
        end;
        case state of
        0: begin
           if (a1>='0')and(a1<='9') then begin
              a2:=a2+a1;
              state:=1;
           end else if a1=' ' then begin
              state:=0;
           end else if a1='+' then begin
              state:=3;
           end else if a1='-' then begin
              state:=4;
           end else if a1='*' then begin
              state:=5;
           end else if a1='/' then begin
              state:=6;
           end else if a1='(' then begin
              state:=7;
           end else if a1=')' then begin
              state:=8;
           end else begin
              state:=101; //error
           end;
        end;
        1: begin
           if (a1>='0')and(a1<='9') then begin
              a2:=a2+a1;
              state:=1;
           end else if a1='.' then begin
              a2:=a2+a1;
              state:=2;
           end else begin
              state:=100; // out
              word_index:=word_index+1;
              opnds.add(word_index, 11, a2);
              the_word:=11;
           end;
        end;
        2: begin
           if (a1>='0')and(a1<='9') then begin
              a2:=a2+a1;
              state:=2;
           end else begin
              state:=100; // out
              word_index:=word_index+1;
              opnds.add(word_index, 12, a2);
              the_word:=12;
           end;
        end;
        3: begin
              state:=100; // out
              the_word:=21;
        end;
        4: begin
              state:=100; // out
              the_word:=26;
           end;
        5: begin
              state:=100; // out
              the_word:=23;
           end;
        6: begin
              state:=100; // out
              the_word:=24;
           end;
        7: begin
              state:=100; // out
              the_word:=27;
           end;
        8: begin
              state:=100; // out
              the_word:=28;
           end;
        end;
     end;
     case last_word of
     1, 27: begin
     //运算符号不能出现在开始
        case the_word of
        11..20, 26, 27: begin
            last_word:=the_word;
            read_word:=the_word;
            e_ptr:=e_ptr-1;
        end;
        else begin
            read_word:=2;
            error_code:=103;
            error_string:=inttostr(last_word)+' with '+inttostr(the_word);
        end;
        end;
     end;
     11..20, 28: begin
     //数字,右括号后不能跟数字,左括号
     //它们后面的负号是减号
        case the_word of
        11..20, 27: begin
            read_word:=2;
            error_code:=103;
            error_string:=inttostr(last_word)+' with '+inttostr(the_word);
        end;
        26: begin
            read_word:=22;
            last_word:=22;
            e_ptr:=e_ptr-1;
        end;
        else begin
            last_word:=the_word;
            read_word:=the_word;
            e_ptr:=e_ptr-1;
        end;
        end;
     end;
     21..26: begin
     //运算符号后面不能跟运算符号,只能跟数字,左括号
        case the_word of
        11..20, 27: begin
            last_word:=the_word;
            read_word:=the_word;
            e_ptr:=e_ptr-1;
        end;
        else begin
            read_word:=2;
            error_code:=103;
            error_string:=inttostr(last_word)+' with '+inttostr(the_word);
        end;
        end;
     end;
     end;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -