编译原理PL0编译程序源代码Word下载.docx

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

编译原理PL0编译程序源代码Word下载.docx

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

编译原理PL0编译程序源代码Word下载.docx

||fname[0]=='

Y'

printf("

是否将符号表写入文件?

//是否输出符号表

tableswitch=(fname[0]=='

init();

//初始化

err=0;

cc=cx=ll=0;

ch='

'

;

if(-1!

=getsym()){

fa=fopen("

虚拟代码.txt"

fas=fopen("

符号表.txt"

addset(nxtlev,declbegsys,statbegsys,symnum);

nxtlev[period]=true;

if(-1==block(0,0,nxtlev)){//调用编译程序

fclose(fa);

fclose(fa1);

fclose(fas);

fclose(fin);

return0;

}

if(sym!

=period){

error(9);

//结尾丢失了句号

if(err!

=0){

printf("

pl0源程序出现错误,退出编译请从第一个错误处开始修改.\n\n"

fprintf(cifa,"

源程序出现错误,请检查"

fprintf(fa1,"

fprintf(fa,"

fprintf(fas,"

}fclose(fa);

fclose(fa1);

}fclose(fin);

}else{

Can'

topenfile!

\n"

}

fclose(cifa);

//printf("

return0;

}

voidinit(){//初始化

inti;

for(i=0;

i<

=255;

i++)

ssym[i]=nul;

//设置单字符符号

ssym['

+'

]=plus;

-'

]=minus;

*'

]=times;

/'

]=slash;

('

]=lparen;

)'

]=rparen;

ssym['

='

]=eql;

'

]=comma;

.'

]=period;

#'

]=neq;

'

]=semicolon;

strcpy(&

(word[0][0]),"

begin"

//保留字设置,以字母顺序排列便于折半查找

(word[1][0]),"

call"

(word[2][0]),"

const"

(word[3][0]),"

do"

(word[4][0]),"

end"

(word[5][0]),"

if"

(word[6][0]),"

odd"

(word[7][0]),"

procedure"

(word[8][0]),"

read"

(word[9][0]),"

then"

(word[10][0]),"

var"

(word[11][0]),"

while"

(word[12][0]),"

write"

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;

(mnemonic[lit][0]),"

lit"

//设置指令名称

(mnemonic[opr][0]),"

opr"

(mnemonic[lod][0]),"

lod"

(mnemonic[sto][0]),"

sto"

(mnemonic[cal][0]),"

cal"

(mnemonic[inte][0]),"

int"

(mnemonic[jmp][0]),"

jmp"

(mnemonic[jpc][0]),"

jpc"

for(i=0;

symnum;

i++){//设置符号集

declbegsys[i]=false;

statbegsys[i]=false;

facbegsys[i]=false;

declbegsys[constsym]=true;

//设置声明开始符号集

declbegsys[varsym]=true;

declbegsys[procsym]=true;

statbegsys[beginsym]=true;

//设置语句开始符号集

statbegsys[callsym]=true;

statbegsys[ifsym]=true;

statbegsys[whilesym]=true;

facbegsys[ident]=true;

//设置因子开始符号集

facbegsys[number]=true;

facbegsys[lparen]=true;

}//用数组实现集合的集合运算

intinset(inte,bool*s){

returns[e];

intaddset(bool*sr,bool*s1,bool*s2,intn){

n;

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

voiderror(intn){//出错处理,打印出错位置和错误编码

charspace[81];

memset(space,32,81);

space[cc-1]=0;

error(%d)"

n);

switch(n){

case1:

\t\t常量说明中的“=”写成“:

=”\n"

fprintf(fa1,"

break;

case2:

\t\t常量说明中的=后应该是数字\n"

case3:

\t\t常量说明符中的表示符应该是=\n"

);

case4:

\t\tconst,var,procedure后应为标识符\n"

fprintf(fa1,"

case5:

\t\t漏掉了“,”或“;

”\n"

case6:

\t\t过程说明后的符号不正确\n"

case7:

\t\t应是语句开始符\n"

case8:

\t\t程序体内语句部分的后跟符不正确\n"

case9:

\t\t程序结尾丢了句号“.”\n\n"

\t\t程序结尾丢了句号“.”\n"

case10:

\t\t语句之间漏了“;

case11:

\t\t标识符拼写错误或未说明\n"

case12:

\t\t赋值语句中,赋值号左部标识符属性应是变量\n"

case13:

\t\t赋值语句左部标识符后应是复制号“:

case14:

\t\tcall后应为标识符\n"

case15:

\t\tcall后标识符属性应为过程\n"

case16:

\t\t条件语句中丢了then\n"

case17:

\t\t丢了“end”或“;

case18:

\t\twhile型循环语句中丢了“do”\n"

case19:

\t\t语句后的符号不正确\n"

case20:

\t\t应为关系运算符\n"

case21:

\t\t表达式内标示符属性不能是过程\n"

case22:

\t\t表达式漏掉了右括号\n"

case23:

\t\t因子后的非法符号\n"

case24:

\t\t表达式的开始符不能是此符号\n"

case25:

\t\t标识符越界\n"

case26:

\t\t非法字符\n"

case31:

\t\t数越界\n"

case32:

\t\tread语句括号中的标识符不是变量\n"

case33:

\t\twrite()或read()中应为完整表达式\n"

default:

\t\t出现未知错误\n"

}err++;

//漏掉空格,读取一个字符,每次读一行,存入line缓冲区,line被getsym取空后再读一//行,被函数getsym调用

intgetch(){

if(cc==ll){

if(feof(fin)){

programincomplete"

return-1;

}

ll=0;

cc=0;

\n%d"

cx);

while(ch!

=10){

if(EOF==fscanf(fin,"

%c"

&

ch)){

line[ll]=0;

break;

}printf("

ch);

line[ll]=ch;

ll++;

}fprintf(cifa,"

ch=line[cc];

cc++;

intgetsym(){//词法分析

inti,j,k,l;

while(ch=='

||ch==10||ch==9)//忽略空格换行TAB

getchdo;

if(ch>

a'

&

ch<

z'

){//以字母开头的为保留字或者标识符

k=0,l=1;

do{

if(k<

al){//al为标识符或保留字最大长度

a[k]=ch;

k++;

if(k==al&

l==1){

error(25);

l=0;

}getchdo;

while(ch>

||ch>

0'

9'

a[k]=0;

//末尾存零

strcpy(id,a);

i=0;

j=norw-1;

do{//开始折半查找

k=(i+j)/2;

if(strcmp(id,word[k])<

j=k-1;

if(strcmp(id,word[k])>

i=k+1;

}while(i<

=j);

if(i-1>

j){//找到即为保留字

sym=wsym[k];

fprintf(cifa,"

%s\t\t%ssym\n"

id,id);

else{//否则为标识符或数字

sym=ident;

%s\t\tident\n"

id);

}else{

if(ch>

){

k=0;

num=0;

sym=number;

do{

num=10*num+ch-'

//数字的数位处理

getchdo;

}while(ch>

k--;

if(k>

nmax){//数字的长度限制

0\t\tnumber\n"

num=0;

error(31);

}else

fprintf(cifa,"

%d\t\tnumber\n"

num);

}else{

if(ch=='

:

){//检测赋值符号,:

只能和=匹配,否则不能识别

if(ch=='

sym=becomes;

=\t\tbecomes\n"

getchdo;

}

else{

sym=nul;

}else{

<

if(ch=='

sym=leq;

//小于等于

fprintf(cifa,"

=\t\tleq\n"

getchdo;

}else{

sym=lss;

//小于

\t\tlss\n"

}

}else{

>

if(ch=='

sym=geq;

//大于等于

fprintf(cifa,"

=\t\tgeq\n"

getchdo;

}else{

sym=gtr;

//大于

\t\tgtr\n"

}

sym=ssym[ch];

//不满足上述条件时按单字//符处理

switch(ch){

case'

fprintf(cifa,"

%c\t\tplus\n"

break;

case'

%c\t\tminus\n"

%c\t\ttimes\n"

%c\t\tslash\n"

%c\t\tlparen\n"

%c\t\trparen\n"

%c\t\teql\n"

%c\t\tcomma\n"

%c\t\tneq\n"

%c\t\tsemicolon\n"

default:

error(26);

if(sym!

=period){//判断是否结束

printf("

fprintf(cifa,"

.\t\tperiod\n"

}return0;

//生成目标代码//目标代码的功能码,层差和位移量

intgen(enumfctx,inty,intz){

if(cx>

=cxmax){//如果目标代码索引过大,报错

Programtoolong"

return-1;

code[cx].f=x;

code[cx].l=y;

code[cx].a=z;

cx++;

//测试字符串

inttest(bool*s1,bool*s2,intn){

if(!

inset(sym,s1)){//测试sym是否属于s1,不属于则报错n

error(n);

while((!

inset(sym,s1))&

(!

inset(sym,s2))){//检测不通过时,不停获得符号,直到它属于需要或补救的集合

getsymdo;

//编译程序主体

//lev:

当前分程序

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

当前位置:首页 > 党团工作 > 入党转正申请

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

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