• 大小: 5KB
    文件类型: .rar
    金币: 1
    下载: 0 次
    发布日期: 2021-05-05
  • 语言: 其他
  • 标签: PL/0  编译器  

资源简介

在《算法+数据结构=程序》一书中,Niklaus Wirth 设计的 PL/0 语言编译器分成两部分,把源语言翻译成中间语言的编译器和中间语言解释器,编译器用的是递归下降的预测分析方法中间语言是一种栈机器代码,其指令集是根据 PL/0 语言的需要来设计的。编译器源码及测试程序可从。一条指令由三个域组成: (1)操作码 f:上面已经列出了所有 8 种操作码。 (2)层次差 l:这里的层次差就是 5.3.2 节介绍嵌套深度时的 n p − n a 。该域仅用于存取指令和调用指令。 (3)多用途 a:在运算指令中,a 的值用来区分不同的运算;在其他情况,a 或是一个数(lit,int),或是一个程序地址(jmp,jpc,cal),或是一个数据地址(lod,sto)。 编译器对 PL/0 源程序进行一遍扫描,并逐行输出源程序。在源程序无错的情况下,编译器每编译完一个分程序,就列出该分程序的代码,这由编译器的 listcode 过程完成。每个分程序的第一条指令是 jmp 指令,其作用是绕过该分程序声明部分产生的代码(即绕过内嵌过程的代码)。listcode 过程没有列出这条代码。 解释器是编译器中的一个过程,若源程序无错,则编译结束时调用解释过程 interpret。由于 PL/0 语言没有输出语句,解释器按执行次序,每遇到对变量赋值时就输出该值。 由于 PL/0 语言是过程嵌套语言,因此程序运行时,活动记录栈中每个活动记录需要包含控制链和访问。活动记录栈的栈顶以外的存储空间作为代码执行过程中所需要的计算栈,无需另外设立计算栈。

资源截图

代码片段和文件信息

// pl/0 compiler with code generation
#include 
#include 
#include “pl0.h“

void error(long n){
    long i;

    printf(“ ****“);
    for (i=1; i<=cc-1; i++){
printf(“ “);
    }
    printf(“^%2d\n“n);
    err++;
}

void getch() {
    if(cc==ll){
if(feof(infile)){
    printf(“************************************\n“);
    printf(“      program incomplete\n“);
    printf(“************************************\n“);
    exit(1);
}
ll=0; cc=0;
printf(“%5d “ cx);
while((!feof(infile))&&((ch=getc(infile))!=‘\n‘)){
    printf(“%c“ch);
    ll=ll+1; line[ll]=ch;
}
printf(“\n“);
ll=ll+1; line[ll]=‘ ‘;
    }
    cc=cc+1; ch=line[cc];
}

void getsym(){
    long ijk;

    while(ch==‘ ‘||ch==‘\t‘){
getch();
    }
    if(isalpha(ch)){  // identified or reserved
k=0;
do{
    if(k a[k]=ch; k=k+1;
    }
    getch();
}while(isalpha(ch)||isdigit(ch));
if(k>=kk){
    kk=k;
}else{
    do{
kk=kk-1; a[kk]=‘ ‘;
    }while(k }
strcpy(ida); i=0; j=norw-1;
do{
    k=(i+j)/2;
    if(strcmp(idword[k])<=0){
j=k-1;
    }
    if(strcmp(idword[k])>=0){
i=k+1;
    }
}while(i<=j);
if(i-1>j){
    sym=wsym[k];
}else{
    sym=ident;
}
    }else if(isdigit(ch)){ // number
k=0; num=0; sym=number;
do{
    num=num*10+(ch-‘0‘);
    k=k+1; getch();
}while(isdigit(ch));
if(k>nmax){
    error(31);
}
    }else if(ch==‘:‘){
getch();
if(ch==‘=‘){
    sym=becomes; getch();
}else{
    sym=nul;
}
    }else if(ch==‘<‘){
getch();
if(ch==‘=‘){
    sym=leq; getch();
}else if(ch==‘>‘){
    sym=neq; getch();
}else{
    sym=lss;
}
    }else if(ch==‘>‘){
getch();
if(ch==‘=‘){
    sym=geq; getch();
}else{
    sym=gtr;
}
    }else{
sym=ssym[(unsigned char)ch]; getch();
    }
}

void gen(enum fct x long y long z){
    if(cx>cxmax){
printf(“program too long\n“);
exit(1);
    }
    code[cx].f=x; code[cx].l=y; code[cx].a=z;
    cx=cx+1;
}

void test(unsigned long s1 unsigned long s2 long n){
    if (!(sym & s1)){
error(n);
s1=s1|s2;
while(!(sym & s1)){
    getsym();
}
    }
}

void enter(enum object k){ // enter object into table
    tx=tx+1;
    strcpy(table[tx].nameid);
    table[tx].kind=k;
    switch(k){
case constant:
    if(num>amax){
error(31);
num = 0;
    }
    table[tx].val=num;
    break;
case variable:
    table[tx].level=lev; table[tx].addr=dx; dx=dx+1;
    break;
case proc:
    table[tx].level=lev;
    break;
    }
}

long position(char* id){ // find identifier id in table
    long i;

    strcpy(table[0].nameid);
    i=tx;
    while(strcmp(table[i].nameid)!=0){
i=i-1;
    }
    return i;
}

void constdeclaration(){
    if(sym==ident){
getsym();
if(sym==eql||sym==becomes){
    if(sym==becomes){
error(1);
    }
    getsym();
    if(sym==number){
enter(constant); getsym();
    }els

 属性            大小     日期    时间   名称
----------- ---------  ---------- -----  ----

     文件       2804  2011-04-19 21:24  pl0.h

     文件      11886  2010-01-28 11:54  pl0.c

    .......       716  2009-11-26 22:48  tests.pl0

     文件       1530  2009-11-09 15:01  multiply.res

     文件        281  2009-11-08 22:54  multiply.pl0

----------- ---------  ---------- -----  ----

                17217                    5


评论

共有 条评论