📄 pl/0编译程序.txt
字号:
end
end; {condition}
begin {语句处理子程序开始}
if sym=ident then {赋值语句处理}
begin i:=position(id) ;
if i=0 then error(11)
else if table[i].kind<>variable then
begin error(12) ; {对非变量赋值}
i:=0;
end;
getsym;
if sym=becomes then getsym
else error(13) ;
expression(fsys) ;
if i<>0 then
with table[i] do gen(sto,1ev-1evel,dr)
end else
if sym=readsym then {读语句处理}
begin getsym;
if sym<>lparen then error(34)
e1se repeat
getsym;
if sym=ident then
i:=position(id)
else i:=0;
if i=0 then error(35)
else with table[i] do
begin gen(opr,0,16) ;
gen(sto,1ev-1evel,dr) ;
end;
getsym;
until sym<>comma;
if sym<>rparen then
begin error(33):
while not(sym in fsys) do getsym;
end else getsym
end else
if sym=writesym then {写语句处理}
begin getsym;
if sym=1paren then
begin repeat
getsym;
if sym=upcomma then
begin getsym;
if sym=ident then i:=position(id)
else i:=0;
if i=0 then error(11)
else chwr[wx]:=id;
wx:=wx+1;
getsym;
if sym=upcomma then getsym
else error(36);
getsym;
expression([rparen,comma]+fsys) ;
gen(opr,0,14) ;
end else
begin getsym;
expression([rparen,comma]+fsys);
gen(opr,0,14) ;
end
until sym<>comma;
if sym<>rparen then error(33)
e1se getsym
end;
gen(opr,0,15) ;
end else
if sym=callsym then {过程语句处理}
begin getsym;
if sym<>ident then error(14)
else begin i:=position(id);
if i=0 then error(11)
else with table[i] do
if kind=proceable then
gen(cal,1ev-level,dr)
else error(15) ;
getsym;
end
end e1se
if sym=ifsym then {条件语句处理}
begin getsym;
condition([thensym,dosym]+fsys);
if sym=thensym then getsym
else error(16);
cxl:=cx;gen(jpc,0,0) ;
statement(fsys) ; code[cxl].a:=cx;
end e1se
if sym=beginsym then {复合语句处理)
begin
getsym;
statement([semicolon,endsym]+fsys) ;
while sym in [semicolon]+statbegsys do
begin if sym=semicolon then getsym
else error(10);
statement([semicolon,endsym]+fsys)
end;
if sym=endsym then getsym
else error(17)
end e1se
if sym=whilesym then {循环语句处理}
begin cxl:=cx;getsym;
condition([dosym]+fsys);
cx2:=cx;gen(jpc,0,0) ;
if sym=dosym then getsym
else error(18) ;
statement(fsys) ;
gen(jmp,0,cxl) ;
code[cx2].a:=cx;
test(fsys,[],19) ;
end;
end;{语句处理子程序结束}
begin {分程序处理子程序开始}
dx:=3; txO:=tx; table[tx].dr:=cx;
gen(jmp,0,0) ;
if 1ev>levmax then error(32);
repeat
if sym=constsym then {常量说明部分处理}
begin getsym;
repeat constdeclaration;
While sym=comma do
begin getsym; constdeclaration;end;
if sym=semicolon then getsym
else error(5);
until sym<>ident
end; {常量说明部分处理结束}
if sym=varsym then {变量说明部分处理}
begin getsym;
repeat vardeclaration;
while sym=comma do
begin getsym;vardeclaration; end;
if sym=semicolon then getsym
else begin error(5) ;getsym;end;
until sym<>ident;
end; {变量说明部分处理结束)
while sym=procsym do {过程说明部分处理}
begin getsym;
if sym=ident then begin enter(proceable) ;getsym;end
else error(4) ;
if sym=semicolon then getsym
else begin error(5) ;getsym;end;
block(lev+1,tx,[semicolon]+fsys) ;
if sym=semicolon then
begin getsym;
test(statbegsys+[ident,procsym],fsys,6)
end
else error(5)
end; {过程说明部分处理结束}
test(statbegsys+[ident],declbegsys,7);
until not(sym in declbegsys) ;
code[table[tx0].dr].a:=cx;
with table[tx0] do dr:=cx; {代码开始地址}
cxO:=cx;gen(int,0,dx);
statement([semicolon,endsym]+fsys);
gen(opr,0,0); {返回}
test(fsys,[],8) ;
listcode;
end; {分程序处理结束}
procedure interpret; {执行目录代码子程序}
const stacksize=500;
var p,b,t:integer;{p:程序地址寄存器, b:基地址寄存器, t:栈顶地址寄存器}
i:instruction; {指令寄存器}
s:array[1..stacksize] of integer;{数据存储}
function base(l:integer):integer;
var b1:integer:
begin b1:=b; {顺静态链求层差为1的基地址}
while l>0 do
begin b1:=s[bl] ;l:=l-1;end;
base:=b1
end; {base}
begin writeln(’start PL/0’) ;
t:=0;b:=1;p:=0;wx:=1;
s[1]:=0;s[2]:=0;s[3]:=0;
repeat
i:=code[p] ;p:=p+1;
with i do
case f of
lit:begin t:=t+1;s[t]:=a;end;
opr:case a of {运算}
0:begin t:=b-1;p:=s[t+3] ;b:=s[t+2] end;{返回}
1: s[t]:=-s[t] ;
2:begin t:=t-1;s[t]:=s[t]+s[t+1] end;
3:begin t:=t-1;s[t]:=s[t]-s[t+1] end;
4:begin t:=t-1;s[t]:=s[t]*s[t+1] end;
5:begin t:=t-1;s[t]:=s[t] div s[t+1] end;
6: s[t]:=ord(odd(s[t]));
8:begin t:=t-1;s[t]:=ord(s[t]=s[t+1]) end;
9:begin t:=t-1;s[t]:=ord(s[t]<>s[t+1]) end;
10:begin t:=t-1;s[t]:=ord(s[t]<s[t+1]) end;
11:begin t:=t-1;s[t]:=ord(s[t]>=s[t+1]) end;
12:begin t:=t-1;s[t]:=ord(s[t]>s[t+1]) end;
13:begin t:=t-1;s[t]:=ord(s[t]<=s[t+1]) end;
14:begin writeln(fw2);write(fw2,chwr[wx]) ;
write(fwZ,s[t]) ;t:=t-1;wx:=wx+1;
end;
15:writeln(fw2) ;
16:begin t:=t+1; read(fi,s[t]) ;end;
end;
lod: begin t:=t+1;s[t]:=s[base(l)+a] end;
sto:begin s[base(l)+a]:=s[t] ;
t:=t-1;
end;
cal: begin {generte new block mark}
s[t+1]:=base(l) ;s[t+2]:=b;
s[t+3]:=p;b:=t+l;p:=a;
end;
int:t:=t+a;
jmp:p:=a;
jpc:begin if s[t]=0 then p:=a;
t:=t - 1;
end
end {with,case }
until p=0;
write(’ end PL/0’);
end; {interpret}
begin {主程序开始}
reset(ff);reset(fi);rewrite(fW2) ;
for ch:=’a’ to ’;’ do ssym[ch]:=nul;
word[1]:=’begin ’ ; word[2]:=’call ’ ;
word[3]:=’const ’ ; word[4]:=’do ’ ;
word[5]:=’end ’ ; word[6]:=’if ’ ;
word[7]:=’odd ’ ; word[8]:=’procedure ’ ;
word[9]:=’read ’ ; word[10]:=’then ’ ;
word[11]:=’var ’ ; word[12]:=’while ’ ;
word[13]:=’write ’ ;
wsym[1]:=beginsym; wsym[2]:=callsym;
wsym[3]:=constsym; wsym[4]:=dosym;
wsym[5]:=endsym; wsym[6]:=ifsym;
wsym[7]:=oddsym; wsym[8]:=procsym;
wsym[9]:=readsym; wsym[10]:=thensym;
wsym[11]:=varsym; wsym[12]:=whilesym;
wsym[13]:=writesym;
ssym[’+’]:=plus; ssym[’-’]:=minus;
ssym['*’]:=times; ssym[’/’]:=slash;
ssym[’(’]:=lparen; ssym[’)’]:=rparen;
ssym[’=’]:=eql; ssym[’,’]:=comma;
ssym[’.’]:=period; ssym[’ ;’]:=semicolon;
ssym[’’’’]:=upcomma;
mnemonic[lit]:=’1it’ ; mnemonic[opr]:=’opr’ ;
mnemonic[lod]:=’lod’ ; mnemonic[sto]:=’sto’ ;
mnemonic[cal]:=’cal’ ; mnemonic[int]:=’int’ ;
mnemonic[jmp]:=’jmp’ ; mnemonic[jpc]:=’jpc’ ;
declbegsys:=[constsym,varsym,procsym];
statbegsys:=[beginsym,callsym,ifsym,whilesym];
facbegsys:=[ident,number,lparen];
err:=0;cw:=1;wx:=1;
cc:=0;cx:=0;ll:=0;ch:=’ ’;kk:=al;getsym;
block(O,0,[period]+declbegsys+statbegsys);
if sym<>period then error(9);
if err=0 then interpret
else write(fw2,’error in PL/0 program’) ;
99:writeln
end. {主程序结束}
说明
(1)对原PL/0编译程序作了如下修改:
1’增加了输入文件ff和fi,输出文件fw2。
2’增加了保留字read和write,使保留字个数增至13。
3’关系运算符中的>=、<=和<>改为在过程getsym中说明。
4’在过程interpret中增加了读和写操作。
(2)预先建立PL/0语言源程序文件ff和其所需要的数据文件fi(文件名预先确定)。
(3)运行时在键盘上根据提示信息键入输出文件fw2的文件名(自行随时确定)。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -