pl0cppWord文件下载.docx

上传人:b****6 文档编号:20527840 上传时间:2023-01-23 格式:DOCX 页数:43 大小:25.91KB
下载 相关 举报
pl0cppWord文件下载.docx_第1页
第1页 / 共43页
pl0cppWord文件下载.docx_第2页
第2页 / 共43页
pl0cppWord文件下载.docx_第3页
第3页 / 共43页
pl0cppWord文件下载.docx_第4页
第4页 / 共43页
pl0cppWord文件下载.docx_第5页
第5页 / 共43页
点击查看更多>>
下载资源
资源描述

pl0cppWord文件下载.docx

《pl0cppWord文件下载.docx》由会员分享,可在线阅读,更多相关《pl0cppWord文件下载.docx(43页珍藏版)》请在冰豆网上搜索。

pl0cppWord文件下载.docx

fa1=fopen("

fa1.tmp"

"

w"

fprintf(fa1,"

%s\n"

init();

//初始化

err=0;

cc=cx=ll=0;

ch='

'

;

if(-1!

=getsym())

{

fa=fopen("

fa.tmp"

fas=fopen("

fas.tmp"

addset(nxtlev,declbegsys,statbegsys,symnum);

nxtlev[period]=true;

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

{

fclose(fa);

fclose(fa1);

fclose(fas);

fclose(fin);

printf("

\n"

return0;

}

fclose(fa);

fclose(fa1);

fclose(fas);

if(sym!

=period)

error(9);

if(err==0)

fa2=fopen("

fa2.tmp"

interpret();

//调用解释执行程序

fclose(fa2);

else

Errorsinpl/0program"

}

fclose(fin);

}

else

printf("

Can'

topenfile!

\n"

printf("

return0;

}

voidinit()

inti;

//设置单字符符号

for(i=0;

i<

=255;

i++)

ssym[i]=nul;

ssym['

+'

]=plus;

-'

]=minus;

*'

]=times;

/'

]=slash;

('

]=lparen;

)'

]=rparen;

='

]=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;

//设置指令名称

strcpy(&

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

declbegsys[i]=false;

statbegsys[i]=false;

facbegsys[i]=false;

/*PL/0C-代码432-434页--LAN*/

/*设置声明开始符号集*/

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)

for(i=0;

i<

n;

i++)

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

intsubset(bool*sr,bool*s1,bool*s2,intn)

sr[i]=s1[i]&

&

(!

s2[i]);

intmulset(bool*sr,bool*s1,bool*s2,intn)

s2[i];

*出错处理,打印错误位置和错误编码

voiderror(intn)

charspace[81];

memset(space,32,81);

space[cc-1]=0;

//出错时当前符号已经读完,所以cc-1

****%s!

%d\n"

space,n);

fprintf(fa1,"

err++;

*漏掉空格,读取一格字符

*

*每次读一行,存入line环从区,line被getsym取空后再读一行

*被函数getsym调用

intgetch()

if(cc==ll)

if(feof(fin))

printf("

programincomplete"

return-1;

ll=0;

cc=0;

%d"

cx);

while(ch!

=10)

//fscanf(fin,"

%c"

&

ch)

if(EOF==fscanf(fin,"

ch))

line[ll]=0;

break;

ch);

fprintf(fa1,"

line[ll]=ch;

ll++;

ch=line[cc];

cc++;

*词法分析,获取一个符号

intgetsym()

inti,j,k;

while(ch=='

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

getchdo;

if(ch>

a'

ch<

z'

)/*名字或保留字以a..z开头*/

k=0;

do{

if(k<

al)

a[k]=ch;

k++;

getchdo;

}while(ch>

&

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])<

=0)

j=k-1;

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

i=k+1;

}while(i<

=j);

if(i-1>

j)

sym=wsym[k];

else/*搜索失败,则是名字或数字*/

sym=ident;

if(ch>

)/*检测是否为数字,以0..9开头*/

k=0;

num=0;

sym=number;

do{

//435

num=10*num+ch-'

getchdo;

}while(ch>

//获取数字的值

k--;

if(k>

nmax)

error(30);

else

if(ch=='

:

)//检测赋值符号

if(ch=='

{

sym=becomes;

getchdo;

}

else

sym=nul;

//不能识别的符号

<

)//检测小于或小于等于符号

getch();

if(ch=='

{

sym=leq;

getchdo;

}

else

sym=lss;

>

)//检测大于或大于等于符号

if(ch=='

{

sym=geq;

getchdo;

}

else

sym=gtr;

sym=ssym[ch];

//当符号不满足上述条件时,全部按照单符号字符处理

//getchdo;

//richard

if(sym!

=period)

//endrichard

*生成虚拟机代码

*

*x:

instruction.f;

*y:

instruction.l;

*z:

instruction.a;

intgen(enumfctx,inty,intz)

if(cx>

=cxmax)

Programtoolong"

//程序过长

return-1;

code[cx].f=x;

code[cx].l=y;

code[cx].a=z;

cx++;

/*

*测试当前符号是否合法

*在某一部分(如一条语句,一个表达式)将要结束时我们希望下一个符号属于某个集合

*(该部分的后跟符号),test负责这项检测,并且负责当检测不通过时的补救措施

*程序在需要检测时指定当前需要的符号集合和补救用的集合(如之前未完成部分的后跟

*符号),以及检测不通过时的错误信号

*s1:

我们需要的符号

*s2:

如果不是我们需要的,则需要一个补救集合

*n:

错误号

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

if(!

inset(sym,s1))

error(n);

//当检测不通过时,不停获取符号,直到它属于需要的集合后补救的集合

while((!

inset(sym,s1))&

(!

inset(sym,s2)))

getsymdo;

/*

*编译程序主体

*lev:

当前分程序所在层

*tx:

名字表当前尾指针

*fsys:

当前模块后跟符号集合

intblock(intlev,inttx,bool*fsys)

intdx;

//名字分配到的相对地址

inttx0;

//保留初始tx

intcx0;

//保留初始cx

/*在下级函数的参数中,符号集合均为值参,但由于使用数组

实现,传递进来的指针为防止下级函数改变上级函数的

集合,开辟新的空间传递给下级函数

*/

dx=3;

tx0=tx;

//记录本层名字的初始位置

table[tx].adr=cx;

gendo(jmp,0,0);

if(lev>

levmax)

error(32);

do{

if(sym==constsym)//收到常量声明符号,开始处理常量声明

constdeclarationdo(&

tx,lev,&

dx);

while(sym==comma)

getsymdo;

constdeclarationdo(&

//dx的值会被constdeclaration改变,

}//使用指针

if(sym==semicolon)

//437

/*438页*/

error(5);

/*漏掉了逗号或者分号*/

}while(sym==ident);

if(sym==varsym)/*收到变量声明符号,开始处理变量声明*/

vardeclarationdo(&

while(sym==comma){

vardeclarationdo(&

if(sym==semicolon)

while(sym==procsym)/*收到过程声明符号,开始处理过程声明*/

if(sym==ident)

enter(procedur,&

/*记录过程名字*/

getsymdo;

error(4);

/*procedure后应为标志符*/

if(sym==semicolon)

error(5);

/*漏掉了分号*/

memcpy(nxtlev,fsys,sizeof(bool)*symnum);

nxtlev[semicolon]=true;

if(-1==block(lev+1,tx,nxtlev))

return-1;

/*递归调用*/

memcpy(nxtlev,statbegsys,sizeof(bool)*symnum);

nxtlev[ident]=true;

nxtlev[procsym]=true;

testdo(nxtlev,fsys,6);

memcpy(nxtlev,statbegsys,sizeof(bool)*symnum);

nxtlev[ident]=true;

nxtlev[period]=true;

testdo(nxtlev,declbegsys,7);

}while(inset(sym,declbegsys));

/*直到没有声明符号*/

code[table[tx0].adr].a=cx;

/*开始生成当前过程代码*/

table[tx0].adr=cx;

/*当前过程代码地址*/

table[tx0].size=dx;

/*声明部分中每增加一条声明都会给dx增加1,声明

部分已经结束,dx就是当前过程数据的size*/

cx0=cx;

gendo(inte,0,dx);

/*生成分配内存代码*/

if(tableswitch)/*输出名字表*/

TABLE:

if(tx0+1>

tx)

NULL\n"

for(i=tx0+1;

i<

=tx;

switch(table[i].kind)

caseconstant:

printf("

%dconst%s"

i,table[i].name);

val=%d\n"

table[i].val);

fprintf(fas,"

casevariable:

%dvar%s"

lev=%daddr=%d\n"

table[i].level,table[i].adr);

fprint

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

当前位置:首页 > 成人教育 > 远程网络教育

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

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