编译原理PL0编译程序源代码Word下载.docx
- 文档编号:16735441
- 上传时间:2022-11-25
- 格式:DOCX
- 页数:35
- 大小:24.15KB
编译原理PL0编译程序源代码Word下载.docx
《编译原理PL0编译程序源代码Word下载.docx》由会员分享,可在线阅读,更多相关《编译原理PL0编译程序源代码Word下载.docx(35页珍藏版)》请在冰豆网上搜索。
||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:
当前分程序
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 PL0 编译程序 源代码