PL0源程序编译原理实验代码.docx

上传人:b****5 文档编号:4387208 上传时间:2022-12-01 格式:DOCX 页数:26 大小:20.07KB
下载 相关 举报
PL0源程序编译原理实验代码.docx_第1页
第1页 / 共26页
PL0源程序编译原理实验代码.docx_第2页
第2页 / 共26页
PL0源程序编译原理实验代码.docx_第3页
第3页 / 共26页
PL0源程序编译原理实验代码.docx_第4页
第4页 / 共26页
PL0源程序编译原理实验代码.docx_第5页
第5页 / 共26页
点击查看更多>>
下载资源
资源描述

PL0源程序编译原理实验代码.docx

《PL0源程序编译原理实验代码.docx》由会员分享,可在线阅读,更多相关《PL0源程序编译原理实验代码.docx(26页珍藏版)》请在冰豆网上搜索。

PL0源程序编译原理实验代码.docx

PL0源程序编译原理实验代码

附件1小组成员:

程序清单

Main.c

#include

#include

#include

voiderror(intn);

voidgetsym();

//voidenter(enumobjectk,int*ptx,intlev,int*pdx);

intposition(char*idt,inttx);

intconstdeclaration(int*ptx,intlev,int*pdx);

intvardeclaration(int*ptx,intlev,int*pdx);

intfactor(int*ptx,intlev);

intterm(int*ptx,intlev);

intexpression(int*ptx,intlev);

intstatement(int*ptx,intlev);

intblock();

enumobject{constant,variable,procedure};

structtab{charname[14];

enumobjectkind;

intval;

intlevel;

intadr;

intsize;

}table[100];

enumsymbol{

nul,ident,number,plus,minus,times,slash,oddsym,eql,neq,lss,leq,gtr,geq,lparen,rparen,comma,semicolon,

period,becomes,beginsym,endsym,ifsym,thensym,whilesym,writesym,readsym,dosym,callsym,constsym,varsym,

procsym,progsym,};

enumsymbolsym=nul;

enumsymbolmulop;

enumsymbolwsym[14];

enumsymbolssym[256];

charch='';

char*str;

charword[14][10]={"begin","call","const","do","end","if","odd","procedure","program","read","then","var","while","write"};//设置保留字名字

intnum;

intlev=0;

inttx=0;

intk;

int*mm;

//=(int*)malloc(sizeof(int));

char*id,sign[14];

chara[14];

FILE*fp1,*fp2,*fp3;

voiderror(intn){

switch(n){

case1:

printf("常数说明中的\"=\"写成了\":

=\"。

\n");

break;

case2:

printf("常数说明中\"=\"后应是数字。

\n");

break;

case3:

printf("常数说明中的标识符后应是\"=\"。

\n");

break;

case4:

printf("program,const,var,procedure后应为标识符。

\n");

break;

case5:

printf("漏掉了\",\"或\";\"。

\n");

break;

case6:

printf("过程说明的符号不正确。

\n");

break;

case7:

printf("应该是语句的开始符。

\n");

break;

case8:

printf("程序体内语句部分的后跟符不正确。

\n");

break;

case9:

printf("程序的结尾丢了句号\".\"。

\n");

break;

case10:

printf("语句之间漏了\";\"。

\n");

break;

case11:

printf("标识符未说明。

\n");

break;

case12:

printf("赋值语句中,赋值号左部标识符属性应是变量。

\n");

break;

case13:

printf("赋值语句左部标识符后应是赋值号\":

=\"。

\n");

break;

case14:

printf("call后应为标识符。

\n");

break;

case15:

printf("call后标识符属性应为过程。

\n");

break;

case16:

printf("条件语句中丢了\"then\"。

\n");

break;

case17:

printf("丢了\"end\"或\";\"。

\n");

break;

case18:

printf("while型循环语句中丢了\"do\"。

\n");

break;

case19:

printf("语句后的符号不正确。

\n");

break;

case20:

printf("应为关系运算符。

\n");

break;

case21:

printf("表达式内标识符属性不能是过程。

\n");

break;

case22:

printf("表达式中漏掉右括号\")\"。

\n");

break;

case23:

printf("因子后的非法符号。

\n");

break;

case24:

printf("表达式的开始符不能是此符号。

\n");

break;

case25:

printf("不能识别的符号。

\n");

break;

case26:

printf("程序的层次越界。

\n");

break;

case27:

printf("程序应该以program保留字开始。

\n");

break;

case28:

printf("程序没有程序主体。

\n");

break;

case31:

printf("数越界。

\n");

break;

case32:

printf("read语句括号中的标识符不是变量。

\n");

break;

case33:

printf("read/write单词后应为左括号。

\n");

break;

case34:

printf("read/write语句括号中的标识符应是申明过的变量。

\n");

break;

case35:

printf("read/write语句没有右括号。

\n");

}

}

voidgetsym(){

inti,n=1,l=0;

intj,m;

do{

while(ch==''||ch==10||ch==9){

if(ch==10)

n++;

ch=fgetc(fp1);

}

if(ch>='a'&&ch<='z'){//名字或保留字以字母开头

k=0;

do{

if(k<10){

a[k]=ch;

k+=1;

}

ch=fgetc(fp1);

}while(ch>='a'&&ch<='z'||ch>='0'&&ch<='9');//读取一串字符

a[k]='\0';//字符串最后置结束符

id=a;//单词自身值赋给id

for(i=0;i<14;i++){

for(j=0;j

if(a[j]==word[i][j])//搜索当前字符是否为保留字

continue;

else

break;

}

if(j==k&&word[i][j]=='\0'){

sym=wsym[i];

break;

}

if(j==k&&word[i][j]!

='\0'){

sym=ident;

break;

}

}

if(i>13)

sym=ident;//将字符串类别值赋给sym

}

elseif(ch>='0'&&ch<='9'){//检测是否为数字:

以0..9开头

k=0;

num=0;

sym=number;

do{

a[k]=ch;

num=10*num+(ch-'0');

k+=1;

ch=fgetc(fp1);

}while(ch>='0'&&ch<='9');//读取数字,并转换为数

k--;

id=a;

if(k>14){

num=0;

error(31);//数字位数超过14位出错

printf("第%d行出错\n",n);

k=0;

*(id+k)='0';

a[k]='0';

}

}

elseif(ch==':

'){//检测赋值符号

k=0;

ch=fgetc(fp1);

*(id+k)=':

';

a[k]=':

';

if(ch=='='){

sym=becomes;

k=k+1;

*(id+k)='=';

a[k]='=';

ch=fgetc(fp1);

}

else{

error(25);

sym=nul;//不能识别的符号

printf("第%d行出错\n",n);

}

}

elseif(ch=='<'){//检测小于或小于等于符号

k=0;

ch=fgetc(fp1);

*(id+k)='<';

a[k]='<';

if(ch=='='){

sym=leq;

k+=1;

*(id+k)='=';

a[k]='=';

ch=fgetc(fp1);

}

else

sym=lss;

}

elseif(ch=='>'){//检测大于或大于等于符号

k=0;

ch=fgetc(fp1);

*(id+k)='>';

a[k]='>';

if(ch=='='){

sym=geq;

k+=1;

*(id+k)='=';

a[k]='=';

ch=fgetc(fp1);

}

else

sym=gtr;

}

elseif(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')'||ch==','||ch=='.'||ch=='#'||ch==';'||ch=='='){//单字符符号处理

sym=ssym[ch];

k=0;

a[k]=ch;

id=a;

ch=fgetc(fp1);

}

else{//当符号不能满足上述条件时,全部按不能识别的符号处理

sym=nul;

k=0;

a[k]=ch;

id=a;

error(25);

printf("第%d行出错\n",n);

ch=fgetc(fp1);

}

switch(sym){

casenul:

str="nul";break;

caseident:

str="ident";break;

casenumber:

str="number";break;

caseplus:

str="plus";break;

caseminus:

str="minus";break;

casetimes:

str="times";break;

caseslash:

str="slash";break;

caseoddsym:

str="oddsym";break;

caseeql:

str="eql";break;

caseneq:

str="neq";break;

caselss:

str="lss";break;

caseleq:

str="leq";break;

casegtr:

str="gtr";break;

casegeq:

str="geq";break;

caselparen:

str="lparen";break;

caserparen:

str="rparen";break;

casecomma:

str="comma";break;

casesemicolon:

str="semicolon";break;

caseperiod:

str="period";break;

casebecomes:

str="becomes";break;

casebeginsym:

str="beginsym";break;

caseendsym:

str="endsym";break;

caseifsym:

str="ifsym";break;

casethensym:

str="thensym";break;

casewhilesym:

str="whilesym";break;

casewritesym:

str="writesym";break;

casereadsym:

str="readsym";break;

casedosym:

str="dosym";break;

casecallsym:

str="callsym";break;

caseconstsym:

str="constsym";break;

casevarsym:

str="varsym";break;

caseprocsym:

str="procsym";break;

caseprogsym:

str="progsym";break;

}

printf("(");

for(m=0;m<=k;m++)

printf("%c",*(id+m));

*(id+k+1)='\0';

printf("\t");

printf("%s)",str);

printf("\n");

fprintf(fp2,"(%s%s)",id,str);

fprintf(fp2,"\n");

l++;

}while(sym==nul&&l<10);

}

voidenter(enumobjectk,int*ptx,intlev,int*pdx)

{

//mm=(int*)malloc(sizeof(int));

intmmm;

(*ptx)++;

*table[(*ptx)].name=*sign;

table[(*ptx)].kind=k;

switch(k){

caseconstant:

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

break;

casevariable:

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

table[(*ptx)].adr=(*pdx);

(*pdx)++;

break;

caseprocedure:

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

break;

}

mmm=*ptx;

//printf("11111111%d2222222\n",mmm);

*mm=mmm;

}

intposition(char*idt,inttx){

inti,j,m;

for(j=0;j

table[0].name[j]=*(idt+j);

for(i=tx;i>0;i--){

for(m=0;m

if(table[i].name[m]!

=*(idt+m))

break;

else

continue;

}

if(m==k+1&&table[i].name[m]=='\0'){

returni;

break;

}

else

continue;

}

if(i==0)

return0;

}

/*常量声明处理*/

intconstdeclaration(int*ptx,intlev,int*pdx){

if(sym==ident){

*sign=*a;

getsym();

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

if(sym==becomes)

error

(1);

getsym();

if(sym==number)

{

enter(constant,ptx,lev,pdx);

}

else

error

(2);

}

else

error(3);

}

else

error(4);

getsym();

return0;

}

/*变量声明处理*/

intvardeclaration(int*ptx,intlev,int*pdx){

if(sym==ident){

*sign=*a;

enter(variable,ptx,lev,pdx);

getsym();

}

else

error(4);

return0;

}

//因子处理

intfactor(int*ptx,intlev){//******************************************************************factor*************

inti;

while(sym==ident||sym==number||sym==lparen)/*循环直到不是因子开始符号*/

{

if(sym==ident)/*因子为常量或变量*/

{

i=position(id,*ptx);/*查找名字*/

if(i==0)

error(11);/*标示符未声明*/

getsym();

}

elseif(sym==number)/*因子为数*/

{

if(num>2047)/*数字越界*/

{

error(31);

num=0;

}

getsym();

}

else/*因子为表达式*/

{

getsym();

expression(ptx,lev);

if(sym==rparen)

getsym();

else

error(22);/*缺少右括号*/

}

}

return0;

}//***********************************************************factor*********************

//项处理

intterm(int*ptx,intlev)//**************************************************************term*******************

{

//enumsymbolmulop;/*用于保存乘除法符号,定义为全局变量*/

factor(ptx,lev);/*处理因子*/

while(sym==times||sym==slash)

{

getsym();

factor(ptx,lev);

}

return0;

}//*************************************************************term*********************

/*表达式处理*/

intexpression(int*ptx,intlev)//***********************************************************expression*********************

{

enumsymboladdop;/*用于保存正负号*/

if(sym==plus||sym==minus)/*开头的正负号,此时当前表达式被看做一个正或负的项*/

{

addop=sym;//保存开头的正负号

getsym();

term(ptx,lev);

}

else

term(ptx,lev);//处理项

while(sym==plus||sym==minus)

{

getsym();

term(ptx,lev);//处理项

}

return0;

}//****************************************************************expression****************

//条件语句处理

intcondition(int*ptx,intlev){

enumsymbolrelop;

if(sym==oddsym){

getsym();

expression(ptx,lev);

}

else{

expression(ptx,lev);

if(sym!

=eql&&sym!

=neq&&sym!

=lss&&sym!

=leq&&sym!

=gtr&&sym!

=geq)

error(20);

else{

relop=sym;

getsym();

expression(ptx,lev);

}

}

return0;

}

//语句处理

intstatement(int*ptx,intlev){

inti;

if(sym==ident){

i=position(id,*ptx);

if(i==0)

error(11);

else{

if(table[i].kind!

=variable){

error(12);

i=0;

}

else{

getsym();

if(sym==becomes)

getsym();

else

error(13);

expression(ptx,lev);

printf("赋值语句\n");

fprintf(fp2,"赋值语句\n");

}

}

}

elseif(sym==readsym){

getsym();

if(sym!

=lparen)

error(33);

else{

do{

getsym();

if(sym==ident)

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 数学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1