标准实验报告(PL0编译程序)

更新时间:2024-06-30 23:06:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

[标准实验报告]

南昌航空大学实验报告

年月日

课程名称: 编译原理 实验名称: 扩充的PL/0编译程序 班级: 姓名: 同组人:

指导教师评定: 签名:

一、 实验目的

进一步熟悉编译程序的整体框架,给出整个编译程序的流程结构,用C或vc++语言编写程序;并将编制的编译程序进行调试、实现PL/0编译程序。

二、 实验要求

(1)根据所选的程序设计语言,修改并调试。 (2)举出例子程序,在程序中进行编译。

(3)用此编译程序对有关语句进行编译,并输出目标指令。 (4)书写出合格的实验报告。

三、 实验步骤

1.输入文件中变量的声明形如:var a,b,c; 以var保留字开始,不同变量以”,”分隔,最后以”;”结束。

2.read语句格式为read(a)或者read(a,b);

3.write语句格式为write(a),括号里面没有字符串常量,注意与书后的形如write(‘a=’,a)是不相同的。

4.的声明形如:”procedure proname;”不含参数表。 5.一维数组形如:变量类型array 数组名[数组下标]。 6.条件语句形如:if <条件>then<语句> {;else,语句>}

7.扩充的记录型数据类型形如:for 循环语句及带参数的过程。

四、 参考源代码

#include /*#include\#include\#define stacksize 500 typedef enum{ false, true }bool;

1

enum object{

procedur , constant ,variable };

#define norw 13 #define txmax 100 #define nmax 14 #define al 10 #define levmax 3 #define cxmax 200 #define amax 2047 #define symnum 32 enum symbol{ nul, ident, number, plus, minus, times, slash, oddsym, eql, neq, lss, leq, gtr, geq, lparen, rparen, comma, semicolon, period, beginsym, endsym, ifsym, thensym, writesym, readsym, dosym, callsym, varsym, procsym, };

enum fct { lit, opr, lod, sto, cal, inte, jmp, jpc, };

#define fctnum 8 struct instruction { enum fct f; int l; int a; };

FILE* fas; FILE* fa; FILE* fal; FILE* fa2; bool listswitch; bool tableswitch;

becomes, whilesym, constsym, 2

char ch;

enum symbol sym; char id[al+1]; int num; int cc,ll; int cx;

char line[81]; char a [al+1]; int num ; int cc,ll; int cx;

char line [81]; char a [al+1];

struct instruction code [cxmax]; char word [norw][al];

struct instruction code [cxmax]; char word [norw][al];

enum symbol wsym [norw]; enum symbol ssym [256]; char mnemonic [fctnum][5]; bool declbegsys [symnum]; bool statbegsys [symnum]; bool facbegsys [symnum]; bool facstatbegsys[symnum]; struct tablestruct { char name [al]; enum object kind ; int val; int level; int adr; int size; };

struct tablestruct table [txmax]; FILE * fin; FILE * fout; char fname [al]; int err;

3

#define getsymdo if(-1==getsym())return -1 #define getchdo if(-1==getch())return -1

#define testdo(a,b,c) if(-1==test(a,b,c))return -1 #define gendo(a,b,c) if(-1==gen(a,b,c))return -1

#define expressiondo(a,b,c) if(-1==expression(a,b,c))return -1 #define factordo(a,b,c) if(-1==factor(a,b,c))return -1 #define termdo(a,b,c) if(-1==term(a,b,c))return -1

#define conditiondo(a,b,c) if(-1==condition(a,b,c))return -1 #define statementdo(a,b,c) if(-1==statement(a,b,c))return -1

#define constdeclarationdo(a,b,c) if(-1==constdeclaration(a,b,c))return -1 #define vardeclarationdo(a,b,c) if(-1==vardeclaration(a,b,c))return -1 void error(int n); int getsym(); int getch(); void init();

int gen(enum fct x,int y,int z); int test(bool *sl,bool *s2,int n); int inset (int e,bool *s);

int addset (bool* sr,bool* sl,bool *s2,int n); int subset (bool* sr,bool* sl,bool *s2,int n); int mulset (bool* sr,bool* sl,bool *s2,int n); int block (int lev,int tx,bool* fsys); void interpret();

int factor (bool* fays,int * ptx,int lev); int term (bool* fays,int * ptx,int lev); int condition (bool* fays,int * ptx,int lev); int expression (bool* fays,int * ptx,int lev); int statement (bool* fays,int * ptx,int lev); void listcode(int cx0);

int vardeclaration (int * ptx,int lev,int * pdx); int constdeclaration (int * ptx,int lev ,int * pdx); int position (char * idt,int tx);

void enter (enum object k,int * ptx ,int lev ,int *pdx); int base (int l,int * s,int b);

int main()

{bool nxtlev[symnum]; printf(\

4

scanf(\fin=fopen(fname,\if(fin)

{printf(\scanf(\

/*listwitch=(fname[0]=='y'||fname[0]=='Y');*/ printf(\scanf(\

tableswitch=(fname[0]=='y'||fname[0]=='Y'); fal=fopen(\fprintf(fal,\fprintf(fal,\init(); err=0;

cc=cx=ll=0; ch='';

if(-1 !=getsym())

{ fa=fopen(\fas=fopen(\

addset(nxtlev,declbegsys,statbegsys,symnum); nxtlev[period]=true;

if(-1==block(0,0,nxtlev)) {

fclose(fa); fclose(fal); fclose(fas); fclose(fin); printf(\return 0; }

fclose(fa); fclose(fal); fclose(fas); if(sym!=period) {error(9); }

if(err==0)

{fa2=fopen(\

5

interpret(); fclose(fa2); } else

{printf(\ } }

fclose(fin); } else

{printf(\ }

printf(\ return 0; }

/*chushihua*/

void init() { int i;

for (i=0;i<=255;i++) {ssym[i]=nul; }

ssym['+']=plus; ssym['-']=minus; ssym['*']=times; ssym['/']=slash; ssym['(']=lparen; ssym[')']=rparen; ssym['=']=eql; ssym[',']=comma; ssym['.']=period; ssym['#']=neq;

ssym[';']=semicolon;

strcpy(&(word[0][0]),\strcpy(&(word[1][0]),\strcpy(&(word[2][0]),\strcpy(&(word[3][0]),\

6

strcpy(&(word[4][0]),\strcpy(&(word[5][0]),\strcpy(&(word[6][0]),\

strcpy(&(word[7][0]),\strcpy(&(word[8][0]),\strcpy(&(word[9][0]),\strcpy(&(word[10][0]),\strcpy(&(word[11][0]),\strcpy(&(word[12][0]),\

wsym[0]=beginsym; wsym[1]=callsym; wsym[2]=constsym; wsym[3]=dosym; wsym[4]=endsym; wsym[5]=ifsym; wsym[6]=oddsym; wsym[7]=procsym; wsym[8]=readsym; wsym[9]=thensym; wsym[10]=varsym; wsym[11]=whilesym; wsym[12]=writesym;

strcpy(&(mnemonic[lit][0]),\strcpy(&(mnemonic[opr][0]),\strcpy(&(mnemonic[lod][0]),\strcpy(&(mnemonic[sto][0]),\strcpy(&(mnemonic[cal][0]),\strcpy(&(mnemonic[inte][0]),\strcpy(&(mnemonic[jmp][0]),\strcpy(&(mnemonic[jpc][0]),\

for(i=0;i

declbegsys[i]=false; statbegsys[i]=false;

7

facbegsys[i]=false; }

declbegsys[constsym]=true; declbegsys[varsym]=true; declbegsys[procsym]=true;

statbegsys[beginsym]=true; statbegsys[callsym]=true; statbegsys[ifsym]=true; statbegsys[whilesym]=true;

facstatbegsys[ident]=true; facstatbegsys[number]=true; facstatbegsys[lparen]=true; }

int inset(int e,bool*s) {

return s[e]; }

int addset(bool* sr,bool * s1,bool* s2,int n) { int i ;

for(i=0;i

sr[i]=s1[i]||s2[i]; }

return 0; }

int subset(bool* sr,bool * s1,bool* s2,int n) {

8

int i ;

for(i=0;i

sr[i]=s1[i]&&(!s2[i]); }

return 0; }

int mulset(bool* sr,bool * s1,bool* s2,int n) { int i ;

for(i=0;i

sr[i]=s1[i]&&(s2[i]); }

return 0; }

void error(int n) {

char space[81];

memset(space,32,81); space[cc-1]=0;

printf(\

fprintf(fal,\err++; }

int getch() {

if(cc==ll) {

if(feof(fin)) {

printf(\ return -1; } ll=0;

9

cc=0; printf(\ fprintf(fal,\ ch=''; while(ch!=10) { if(EOF==fscanf(fin,\ { line[ll]=0; break; } printf(\ fprintf(fal,\ line[ll]=ch; ++ll; } printf(\ fprintf(fal,\ } ch=line[cc]; cc++; return 0; } /*****************************8 */ int getsym() { int i,j,k;

while (ch==''||ch==10||ch==9) { getchdo; } if(ch>='a'&& ch<='z') { k=0; do{ if(k

10

} else { if(ch>='0'&&ch<='9') { k=0; num=0; sym=number; do{ num=10*num+ch-'0'; k++; getchdo;

k++; } getchdo; }while(ch>='a'&& ch<='z'||ch>='0'&& ch<='9'); a[k]=0; strcpy(id,a); i=0; j=norw-1 ; do{ k=(i+j)/2 ; if(strcmp(id,word[k])<=0) { j=k-1; }

if(strcmp(id,word[k])>=0) i=k+1; }

while(i<=j); if(i-1>j) { sym=wsym[k]; } else { sym=ident; }

11

}while (ch>='0'&&ch<='9'); k--;

if(k>nmax) { error(30); } } else { if(ch==';') { getchdo; if(ch=='=') { sym=becomes; getchdo; } else { sym=nul; } } else { if (ch=='<') { getchdo; if(ch=='=') { sym=leq; getchdo; } else { sym=lss; } } else

12

{ if(ch=='>')

int gen(enum fct x,int y,int z) {

if(cx>=cxmax) {

printf(\return -1; }

code[cx].f=x; code[cx].l=y;

{ getchdo; if(ch=='=') { sym=geq; getchdo; } else { sym=gtr; } } else { sym=ssym[ch]; if(sym!=period) { getchdo; } } } } } } return 0; }

13

code[cx].a=z; cx++; return 0; }

int test(bool * s1,bool * s2,int n) {if(! inset(sym,s1)) {error(n);

while((! inset(sym,s1))&&(! inset(sym,s2))) {getsymdo; } }

return 0; }

int block(int lev,int tx,bool* fsys) { int i; int dx; int txo; int cxo;

bool nxtlev[symnum]; dx=3; txo=tx;

table[tx].adr=cx; gendo(jmp,0,0); if(lev>levmax) {error(32); } do{

if(sym==constsym) {getsymdo; do

{constdeclarationdo(&tx,lev,&dx); while(sym==comma) {getsymdo;

constdeclarationdo(&tx,lev,&dx); }

14

if (sym==semicolon) {getsymdo; } else

{error(5); }

}while(sym==ident); }

if(sym==varsym) {getsymdo; do{

vardeclarationdo(&tx,lev,&dx); while(sym==comma) {getsymdo;

vardeclarationdo(&tx,lev,&dx); }

if(sym==semicolon) {getsymdo; } else{ error(5); }

}while(sym==ident); }

while(sym==procsym) {getsymdo; if(sym==ident)

{enter(procedur,&tx,lev,&dx); getsymdo; } else

{error(4); }

if(sym==semicolon) {getsymdo; } else

{error(5);

15

}

memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlev[semicolon]=true;

if(-1==block(lev+1,tx,nxtlev)) {return -1; }

if(sym==semicolon) {getsymdo;

memcpy(nxtlev,statbegsys,sizeof(bool) * symnum); nxtlev[ident]=true; nxtlev[procsym]=true; testdo(nxtlev,fsys,6); } else

{error(5); } }

memcpy(nxtlev,statbegsys,sizeof(bool) * symnum); nxtlev[ident]=true; nxtlev[period]=true;

testdo(nxtlev,declbegsys,7); }while(inset(sym,declbegsys)); code[table[txo].adr].a=cx; table[txo].adr=cx; table[txo].size=dx; cxo=cx;

gendo(inte,0,dx); if(tableswitch)

{printf(\if(txo+1>tx)

{printf(\}

for(i=txo+1;i<=tx;i++) {switch(table[i].kind) {case constant:

printf(\printf(\

fprintf(fas,\

16

fprintf(fas,\break;

case variable:

printf(\

printf(\fprintf(fas,\

fprintf(fas,\break;

case procedur:

printf(\

printf(\fprintf(fas,\

fprintf(fas,\break; } }

printf(\}

memcpy(nxtlev,fsys,sizeof(bool) * symnum); nxtlev[semicolon]=true; nxtlev[endsym]=true;

statementdo(nxtlev,&tx,lev); gendo(opr,0,0);

memset(nxtlev,0,sizeof(bool) * symnum); testdo(fsys,nxtlev,8); listcode(cxo); return 0; }

void enter(enum object k , int * ptx , int lev , int * pdx) {

(*ptx)++;

strcpy(table[(*ptx)].name,id); table[(*ptx)].kind=k; switch(k)

{case constant: if(num>amax)

17

{error(31); num=0; }

table[(*ptx)].val=num; break;

case variable:

table[(*ptx)].level=lev; table[(*ptx)].adr=(*pdx); (*pdx)++; break;

case procedur:

table[(*ptx)].level=lev; break; } }

int position(char*idt,int tx) { int i;

strcpy(table[0].name,idt); i=tx;

while(strcmp(table[i].name,idt)!=0) { i--; }

return i; }

int constdecalration(int *ptx,int lev,int *pdx) {

if(sym==ident) {

getsymdo;

if(sym==eql||sym==becomes) {

if(sym==becomes) error(1); getsymdo;

18

if(sym==number){

enter(constant,ptx,lev,pdx); getsymdo; } else {

error(2); } } else {

error(3); } } else {

error(4); }

return 0; }

int constdeclaration(int * ptx,int lev,int * pdx) { if (sym==ident) { getsymdo; if (sym==eql||sym==becomes) { if (sym==becomes) { error(1); } getsymdo; if (sym ==number) { enter(constant,ptx,lev,pdx); getsymdo;

19

} else { error(2); } } else { error(3); } } else { error(4); } return 0; }

int vardeclaration(int* ptx,int lev,int* pdx) {

if (sym==ident) {

enter(variable,ptx,lev,pdx); getsymdo; } else {

error(4); }

return 0; }

void listcode(int cx0) {

int i;

if (listswitch) {

20

for (i=cx0;i

printf(\ fprintf(fa,\ } } }

int statement(bool* fsys,int* ptx,int lev) {

int i,cxl,cx2;

bool nxtlev[symnum]; if (sym==ident) {

i=position(id,*ptx); if (i==0) {

error(11); } else {

if(table[i].kind !=variable) { error(12); i=0; } else { getsymdo; if(sym==becomes) { getsymdo; } else { error(13); } memcpy(nxtlev,fsys,sizeof(bool)*symnum); expressiondo(nxtlev,ptx,lev);

21

if(i!=0) { gendo(sto,lev-table[i].level,table[i].adr); } }

}/*if(i==0)*/ } else {

if(sym==readsym) {

getsymdo;

if(sym!=lparen) {

error(34); } else { do{

getsymdo; if(sym==ident) {

i=position(id,*ptx); } else { i=0; } if(i==0) {

error(35); } else { gendo(sto,lev-table[i].level,table[i].adr) ; }

gendo(opr,0,16); 22

getsymdo; }while(sym==comma); } if(sym!=rparen) { error(33); while(! inset(sym,fsys)) { getsymdo; } } else { getsymdo; } } else { if(sym==writesym) { getsymdo; if(sym==lparen) { do{ getsymdo; memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlev[rparen]=true; nxtlev[comma]=true; expressiondo(nxtlev,ptx,lev); gendo(opr,0,14); }while(sym==comma); if(sym!=rparen) {

23

error(33); } else { getsymdo; } } gendo(opr,0,15); } else {if(sym==callsym) { getsymdo; if(sym!=ident) { error(14); } else { i=position(id,*ptx); if(i==0) { error(11); } else { if(table[i].kind==procedur) { gendo(cal,lev-table[i].level,table[i].adr); } else { error(15); } }

24

getsymdo; } } else { if (sym==ifsym) { getsymdo; memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlev[thensym]=true; nxtlev[dosym]=true; conditiondo(nxtlev,ptx,lev); if(sym==thensym) { getsymdo; } else { error(16); } cxl=cx; gendo(jpc,0,0); statementdo(fsys,ptx,lev); code[cxl].a=cx; } else { if(sym==beginsym) {

25

getsymdo; memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlev[semicolon]=true; nxtlev[endsym]=true; statementdo(nxtlev,ptx,lev); while(inset(sym,statbegsys)||sym==semicolon) { if(sym==semicolon) { getsymdo; } else { error(10); }statementdo(nxtlev,ptx,lev); } if(sym==endsym) { getsymdo; } else { error(17); } } else {

if(sym==whilesym) {

cxl=cx; getsymdo;

memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlev[dosym]=true; conditiondo(nxtlev,ptx,lev); cx2=cx; gendo(jpc,0,0); if(sym==dosym) {

26

getsymdo; } else { error(18); } statementdo(fsys,ptx,lev); gendo(jmp,0,cxl); code[cx2].a=cx; } else { testdo(fsys,nxtlev,19); } } } } }}} return 0; }

int expression(bool * fsys,int * ptx,int lev) { enum symbol addop; bool nxtlev[symnum]; if(sym==plus||sym==minus) { addop=sym; getsymdo; memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlev[plus]=true; nxtlev[minus]=true; termdo(nxtlev,ptx,lev); if(addop==minus) { gendo(opr,0,1); } }

27

else { memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlev[plus]=true; nxtlev[minus]=true; termdo(nxtlev,ptx,lev); } while(sym==plus||sym==minus) { addop=sym; getsymdo; memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlev[plus]=true; nxtlev[minus]=true; termdo(nxtlev,ptx,lev); if(addop==plus) { gendo(opr,0,2); } else { gendo(opr,0,3); } } return 0; }

int term(bool*fsys,int*ptx,int lev) { enum symbol mulop; bool nxtlev[symnum]; memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlev[times]=true; nxtlev[slash]=true; factordo(nxtlev,ptx,lev); while(sym==times||sym==slash) { mulop=sym; getsymdo;

28

factordo(nxtlev,ptx,lev); if(mulop==times) { gendo(opr,0,4); } else { gendo(opr,0,5); } } return 0; }

int factor(bool*fsys,int*ptx,int lev) { int i; bool nxtlev[symnum]; testdo(facbegsys,fsys,24); while(inset(sym,facbegsys)) { if(sym==ident) { i=position(id,*ptx); if(i==0) { error(11); } else { switch(table[i].kind) { case constant: gendo(lit,0,table[i].val); break; case variable: gendo(lod,lev-table[i].level,table[i].adr); break;

29

case procedur: error(21); break; } } getsymdo; } else { if(sym==number) { if(num>amax) { error(31); num=0; } gendo(lit,0,num); getsymdo; } else { if(sym==lparen) { getsymdo;

memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlev[rparen]=true;

expressiondo(nxtlev,ptx,lev); if(sym==rparen) { getsymdo; } else { error(22); } }

30

testdo(fsys,facbegsys,23); } } } return 0; }

int condition(bool*fsys,int*ptx,int lev) { enum symbol relop; bool nxtlev[symnum]; if(sym==oddsym) { getsymdo; expressiondo(fsys,ptx,lev); gendo(opr,0,6); } else { memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlev[eql]=true; nxtlev[neq]=true; nxtlev[lss]=true; nxtlev[leq]=true; nxtlev[gtr]=true; nxtlev[geq]=true; expressiondo(nxtlev,ptx,lev); if(sym!=eql&&sym!=neq&&sym!=lss&&sym!=leq&&sym!=gtr&&sym!=geq) { error(20); } else { relop=sym; getsymdo; expressiondo(fsys,ptx,lev); switch(relop)

31

{

case eql:

case neq: gendo(opr,0,8); break; }

} return 0; }

void interpret() {

int p,b,t;

struct instruction i; int s[stacksize]; printf(\t=0; b=0; p=0;

s[0]=s[1]=s[2]=0; do {

i=code[p];

gendo(opr,0,9);

break;

case lss: gendo(opr,0,10);

break;

case geq: gendo(opr,0,11);

break;

case gtr: gendo(opr,0,12);

break;

case leq: gendo(opr,0,13); break;

}

32

p++;

switch(i.f) {

case lit: s[t]=i.a; t++; break; case opr: switch(i.a) { case 0: t=b;

p=s[t+2]; b=s[t+1]; break; case 1:

s[t-1]=-s[t-1]; break; case 2: t--;

s[t-1]=s[t-1]+s[t]; break; case 3: t--;

s[t-1]=s[t-1]-s[t]; break; case 4: t--;

s[t-1]=s[t-1]*s[t]; break; case 5: t--;

s[t-1]=s[t-1]/s[t]; break; case 6: t--;

s[t-1]=s[t-1]%2; break;

33

case 8: t--;

s[t-1]=(s[t-1]==s[t]); break; case 9: t--;

s[t-1]=(s[t-1]!=s[t]); break; case 10: t--;

s[t-1]=(s[t-1]

s[t-1]=(s[t-1]>=s[t]); break; case 12: t--;

s[t-1]=(s[t-1]>s[t]); break; case 13: t--;

s[t-1]=(s[t-1]<=s[t]); break; case 14:

printf(\fprintf(fa2,\t--; break; case 15: printf(\fprintf(fa2,\break; case 16: printf(\fprintf(fa2,\scanf(\fprintf(fa2,\

34

t++; break; }

break; case lod:

s[t]=s[base(i.l,s,b)+i.a]; t++; break; case sto: t--;

s[t]=s[base(i.l,s,b)+i.a]=s[t]; break; case cal:

s[t]=base(i.l,s,b); s[t+1]=b; s[t+2]=p; b=t; p=i.a; break; case inte: t+=i.a; break; case jmp: p=i.a; break; case jpc: t--;

if(s[t]==0) p=i.a; break; }

}while(p!=0); }

int base(int l,int *s,int b) {

35

int b1; b1=b; while(l>0) {

b1=s[b1]; l--; }

return b1; }

五、 实验结果

1.输入PL/0源程序 const a=10; var b,c; procedure p begin c:=b+a end; begin read (b); while b#0 do begin call p; write(2*c); read(b) end end.

2. 输入分别输入b值的结果 当b=2; 输出结果为24 当b=3;输出结果为26 当b=1;出结果为22 当b=0;结束程序

六、 实验体会

通过该实验,本人学会了应用C语言调试和扩充PL/0编译程序的能力,此实验完成了PL/0词法分析、语法分析、语义分析、代码生成和代码优化等功能,并在此基础上实现了PL/0语言的扩充能力,从实际的应用中深刻领悟了编译程序的原理,更加深刻的学习了理论知识。

36

int b1; b1=b; while(l>0) {

b1=s[b1]; l--; }

return b1; }

五、 实验结果

1.输入PL/0源程序 const a=10; var b,c; procedure p begin c:=b+a end; begin read (b); while b#0 do begin call p; write(2*c); read(b) end end.

2. 输入分别输入b值的结果 当b=2; 输出结果为24 当b=3;输出结果为26 当b=1;出结果为22 当b=0;结束程序

六、 实验体会

通过该实验,本人学会了应用C语言调试和扩充PL/0编译程序的能力,此实验完成了PL/0词法分析、语法分析、语义分析、代码生成和代码优化等功能,并在此基础上实现了PL/0语言的扩充能力,从实际的应用中深刻领悟了编译程序的原理,更加深刻的学习了理论知识。

36

本文来源:https://www.bwwdw.com/article/9ey.html

Top