📄 unit3.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 + -