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

📄 pl/0编译程序.txt

📁 PL/0语言的文法规则 说明 (1)对原PL/0编译程序作了如下修改: 1’增加了输入文件ff和fi,输出文件fw2。 2’增加了保留字read和write
💻 TXT
📖 第 1 页 / 共 2 页
字号:
                 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 + -