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

更新时间:2024-02-27 17:41:01 阅读量: 综合文库 文档下载

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

附件1 小组成员:

程序清单

Main.c

#include #include #include void error(int n); void getsym();

//void enter(enum object k,int *ptx,int lev,int *pdx); int position(char*idt,int tx);

int constdeclaration(int *ptx,int lev,int *pdx); int vardeclaration(int *ptx,int lev,int *pdx); int factor(int*ptx,int lev); int term(int *ptx,int lev); int expression(int *ptx,int lev); int statement(int *ptx,int lev); int block();

enum object{constant,variable,procedure}; struct tab{char name[14]; enum object kind; int val; int level; int adr; int size; }table[100];

enum symbol{

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,}; enum symbol sym=nul; enum symbol mulop; enum symbol wsym[14]; enum symbol ssym[256]; char ch=' '; char *str;

char

word[14][10]={\\设置保留字名字 int num; int lev=0;

int tx=0;

int k; int *mm;

//=(int *)malloc(sizeof(int)); char *id,sign[14]; char a[14];

FILE *fp1,*fp2,*fp3; void error(int n){ switch(n){

case 1:printf(\常数说明中的\\\写成了\\\。\\n\ break;

case 2:printf(\常数说明中\\\后应是数字。\\n\ break;

case 3:printf(\常数说明中的标识符后应是\\\。\\n\

break;

case 4:printf(\后应为标识符。\\n\ break;

case 5:printf(\漏掉了\\\或\\\。\\n\ break;

case 6:printf(\过程说明的符号不正确。\\n\ break;

case 7:printf(\应该是语句的开始符。\\n\ break;

case 8:printf(\程序体内语句部分的后跟符不正确。\\n\ break;

case 9:printf(\程序的结尾丢了句号\\\。\\n\ break;

case 10:printf(\语句之间漏了\\\。\\n\ break; case 11:printf(\标识符未说明。\\n\

break;

case 12:printf(\赋值语句中,赋值号左部标识符属性应是变量。\\n\

break; case 13:printf(\赋值语句左部标识符后应是赋值号\\\。\\n\

break;

case 14:printf(\后应为标识符。\\n\

break;

case 15:printf(\后标识符属性应为过程。\\n\ break; case 16:printf(\条件语句中丢了\\\。\\n\ break; case 17:printf(\丢了\\\或\\\。\\n\ break;

case 18:printf(\型循环语句中丢了\\\。\\n\

break;

case 19:printf(\语句后的符号不正确。\\n\ break;

case 20:printf(\应为关系运算符。\\n\ break;

case 21:printf(\表达式内标识符属性不能是过程。\\n\ break; case 22:printf(\表达式中漏掉右括号\\\)\\\。\\n\ break; case 23:printf(\因子后的非法符号。\\n\

break;

case 24:printf(\表达式的开始符不能是此符号。\\n\ break;

case 25:printf(\不能识别的符号。\\n\

break;

case 26:printf(\程序的层次越界。\\n\ }

break;

case 27:printf(\程序应该以program保留字开始。\\n\ break; case 28:printf(\程序没有程序主体。\\n\ break;

case 31:printf(\数越界。\\n\ break;

case 32:printf(\语句括号中的标识符不是变量。\\n\ break; case 33:printf(\单词后应为左括号。\\n\ break;

case 34:printf(\语句括号中的标识符应是申明过的变量。\\n\ break;

case 35:printf(\语句没有右括号。\\n\}

void getsym(){ int i,n=1,l=0; int j,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]) //搜索当前字符是否为保留字

else break;

continue;

}

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 }

else if(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\ k=0;

*(id+k)='0';

a[k]='0'; } } else if(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\

}

}

else if (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;

}

else if(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;

}

else

if(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\ ch=fgetc(fp1);

}

switch(sym){

case nul:str=\ case ident:str=\ case number:str=\

case plus:str=\ case minus:str=\ case times:str=\ case slash:str=\ case oddsym:str=\ case eql:str=\ case neq:str=\ case lss:str=\ case leq:str=\ case gtr:str=\ case geq:str=\ case lparen:str=\ case rparen:str=\ case comma:str=\

case semicolon:str=\ case period:str=\ case becomes:str=\ case beginsym:str=\ case endsym:str=\ case ifsym:str=\

case thensym:str=\

case whilesym:str=\ case writesym:str=\

case readsym:str=\ case dosym:str=\ case callsym:str=\ case constsym:str=\ case varsym:str=\ case procsym:str=\ case progsym:str=\

}

printf(\

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

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

printf(\ printf(\ printf(\

fprintf(fp2,\

fprintf(fp2,\ l++;

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

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

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

(*ptx)++;

*table[(*ptx)].name=*sign; table[(*ptx)].kind=k; switch(k){

case constant:

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

case variable: table[(*ptx)].level=lev; table[(*ptx)].adr=(*pdx);

(*pdx)++;

break;

case procedure: table[(*ptx)].level=lev; break;

}

mmm=*ptx;

//printf(\ *mm=mmm; }

int position(char *idt,int tx){

int i,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'){ return i; break; } else

continue; } if(i==0) }

return 0;

/*常量声明处理*/

int constdeclaration(int *ptx,int lev,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(); return 0;

/*变量声明处理*/

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

if(sym==ident){ *sign=*a; }

enter(variable,ptx,lev,pdx); getsym();

else

error(4); return 0; }

//因子处理 int

factor(int *ptx,int

lev){ //******************************************************************factor*************

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

{

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

i=position(id,*ptx); /*查找名字*/ if(i==0) error(11); /*标示符未声明*/ getsym();

}

else if(sym==number) /*因子为数*/

{

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

error(31); num=0;

}

getsym(); }

else /*因子为表达式*/ {

getsym();

expression(ptx,lev); if(sym==rparen) getsym(); else

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

} }

return 0;

}

//***********************************************************factor********************* //项处理 int

term(int *ptx,int lev)

//**************************************************************term*******************

{ //enum symbol mulop; /*用于保存乘除法符号,定义为全局变量*/ factor(ptx,lev); /*处理因子*/ while(sym==times||sym==slash) {

getsym(); factor(ptx,lev); }

return 0;

}

//*************************************************************term*********************

/*表达式处理*/

int expression(int *ptx,int lev)//***********************************************************expression********************* {

enum symbol addop; /*用于保存正负号*/

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

{

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

term(ptx,lev);

} else term(ptx,lev); //处理项 while(sym==plus||sym==minus) { }

getsym();

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

return 0;

}

//****************************************************************expression**************** //条件语句处理

int condition(int *ptx,int lev){ enum symbol relop; }

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); } }

return 0;

//语句处理

int statement(int *ptx,int lev){ int i;

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\

else if(sym==readsym){ getsym();

if(sym!=lparen) error(33); else{ do{ getsym();

if(sym==ident) i=position(id,*ptx); else

i=0; if(i==0) error(34);

getsym();

}while(sym==comma);

}

if(sym!=rparen) error(35); else getsym();

printf(\语句\\n\

fprintf(fp2,\语句\\n\

}

else if(sym==writesym){

getsym(); if(sym==lparen){ do{

getsym(); expression(ptx,lev); }while(sym==comma); printf(\语句\\n\

fprintf(fp2,\语句\\n\

if(sym!=rparen)

error(35); else getsym(); }

}

else if(sym==callsym){

getsym();

if(sym!=ident)

error(14);

i=position(id,*ptx);

if(i==0) error(11);

else{ if(table[i].kind!=procedure) error(15); }

getsym();

else{

}

printf(\语句\\n\

fprintf(fp2,\语句\\n\}

else if(sym==ifsym){ getsym(); }

condition(ptx,lev); if(sym==thensym) getsym(); else error(16); statement(ptx,lev); printf(\语句\\n\ fprintf(fp2,\语句\\n\

else if(sym==beginsym){ getsym();

statement(ptx,lev); do{

if(sym==semicolon)

getsym(); else

error(10); statement(ptx,lev); }while(sym==semicolon);

}

printf(\语句\\n\

fprintf(fp2,\语句\\n\ if(sym==endsym){ getsym(); if(sym==procsym) }

block();

else

error(17);

else if(sym==whilesym){

getsym();

condition(ptx,lev); if(sym==dosym) getsym(); else error(18);

statement(ptx,lev);

printf(\语句\\n\

fprintf(fp2,\循环\\n\

} return 0; }

int block(){ int dx=3,tx0; tx0=tx;

if(lev>3) error(26); do{

if(sym==constsym){ getsym();

if(sym==ident){

constdeclaration(&tx,lev,&dx);

while(sym==comma){ getsym();

if(sym==ident)

constdeclaration(&tx,lev,&dx); else error(4); }

if(sym==semicolon) getsym(); else

error(5);

} else

error(4); }

if(sym==varsym){ getsym();

if(sym==ident){

vardeclaration(&tx,lev,&dx);

while(sym==comma){ getsym();

if(sym==ident)

vardeclaration(&tx,lev,&dx); else error(4); }

}

if(sym==semicolon) getsym(); else

error(5);

else

error(4); } if(sym==procsym){

lev++; do{

getsym(); *sign=*a;

if(sym==ident){

enter(procedure,&tx,lev,&dx); getsym();

} else

error(4); if(sym==semicolon)

getsym(); else

error(5);

if(-1==block()) return -1;

if(sym==semicolon) getsym(); else

error(5);

}while(sym==procsym); }

}while(sym!=beginsym); statement(&tx,lev); table[tx0].size=dx; return 0;

}

void main(){

//freopen(\ int i,j,n;

char nn[14];

char file1name[10],file2name[10],file3name[10]; mm=(int *)malloc(sizeof(int)); printf(\输入源程序的文件名:\\t\ scanf(\

getchar(); fp1=fopen(file1name,\ if(!fp1)

printf(\

printf(\输入用于存放词法分析二维表的文件的文件名:\\t\

scanf(\ getchar(); fp2=fopen(file2name,\ if(!fp2)

printf(\

printf(\输入用于存放语法分析TABLE表的文件的文件名:\\t\

scanf(\ getchar(); fp3=fopen(file3name,\

if(!fp3) printf(\

for(j=0;j<255;j++) ssym[j]=nul;

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

ssym[';']=semicolon; 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]=progsym; wsym[9]=readsym; wsym[10]=thensym; wsym[11]=varsym; wsym[12]=whilesym; wsym[13]=writesym; getsym();

if(sym==progsym) {

getsym();

for(n=0;n<=k;n++) nn[n]=a[n]; if(sym==ident) {

getsym();

if(sym==semicolon) getsym(); else

{

error(5); getsym(); } }

else {

error(4); getsym(); } } else

{

error(27); getsym(); } if(-1==block())

{

fclose(fp1); fclose(fp2); fclose(fp3); }

if(sym!=period) error(9);

printf(\

printf(\

printf(\fprintf(fp3,\

fprintf(fp3,\for(i=1;i<=(*mm);i++) switch(table[i].kind){

case constant: printf(\

printf(\

fprintf(fp3,\ fprintf(fp3,\

break;

case variable:

printf(\

printf(\ fprintf(fp3,\ fprintf(fp3,\

adr=%d\\n\ break;

case procedure: printf(\ printf(\

adr=%d

size=%d\\n\

fprintf(fp3,\ fprintf(fp3,\ size=%d\\n\ }

}

break;

adr=%d

printf(\fclose(fp1); fclose(fp2); fclose(fp3);

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

Top