编译原理增加数据类型Word文档格式.docx

上传人:b****6 文档编号:16183229 上传时间:2022-11-21 格式:DOCX 页数:67 大小:33.58KB
下载 相关 举报
编译原理增加数据类型Word文档格式.docx_第1页
第1页 / 共67页
编译原理增加数据类型Word文档格式.docx_第2页
第2页 / 共67页
编译原理增加数据类型Word文档格式.docx_第3页
第3页 / 共67页
编译原理增加数据类型Word文档格式.docx_第4页
第4页 / 共67页
编译原理增加数据类型Word文档格式.docx_第5页
第5页 / 共67页
点击查看更多>>
下载资源
资源描述

编译原理增加数据类型Word文档格式.docx

《编译原理增加数据类型Word文档格式.docx》由会员分享,可在线阅读,更多相关《编译原理增加数据类型Word文档格式.docx(67页珍藏版)》请在冰豆网上搜索。

编译原理增加数据类型Word文档格式.docx

structinstruction

{

enumfctf;

//虚拟机代码指令

intl;

//引用层与声明层的层差

doublea;

//根据f的不同而不同,参考课本

FILE*fas;

//输出名字表

FILE*fa;

//输出虚拟机代码

FILE*fa1;

//输出源文件及其各行对应的首地址

FILE*fa2;

//输出结果

boollistswitch;

booltableswitch;

charch;

//获取字符的缓冲区

enumsymbolsym;

charid[al+1];

doublenum;

intcc,ll;

//cc表示当前字符的位置

intcx;

//虚拟机代码指针

charline[81];

//读取行缓冲区

chara[al+1];

//临时符号,多出的一个字节用于表示字符串的结尾

structinstructioncode[cxmax];

//存放虚拟机代码的数组

charword[norw][al];

//保留字

enumsymbolwsym[norw];

//保留字对应的符号值

enumsymbolssym[256];

//单符号的符号值

charmnemonic[fctnum][5];

//虚拟机代码指令的名称

booldeclbegsys[symnum];

//表示声明开始的符号集合

boolstatbegsys[symnum];

//表示语句开始的符号集合

boolfacbegsys[symnum];

//表示因子开始的符号集合

//名字表结构

structtablestruct

charname[al];

//名字

//enumdatatypetype;

//数据类型:

integer,character,doub,

enumobjectkind;

//类型:

const,var,array,procedure

doubleval;

//数值,仅const使用,使用双精度浮点型

intlevel;

//所处层

intadr;

//地址

intsize;

//需分配的数据空间

structtablestructtable[txmax];

//名字表

FILE*fin;

FILE*fout;

charfname[al];

interr;

//错误计数器,每出一次错误,其加一

#definegetsymdoif(-1==getsym())return-1

#definegetchdoif(-1==getch())return-1

#definetestdo(a,b,c)if(-1==test(a,b,c))return-1

#definegendo(a,b,c)if(-1==gen(a,b,c))return-1

#defineexpressiondo(a,b,c)if(-1==expression_r(a,b,c))return-1

#definefactordo(a,b,c)if(-1==factor(a,b,c))return-1

#definetermdo(a,b,c)if(-1==term(a,b,c))return-1

#defineconditiondo(a,b,c)if(-1==condition(a,b,c))return-1

#definestatementdo(a,b,c)if(-1==statement(a,b,c))return-1

#defineconstdeclarationdo(a,b,c)if(-1==constdeclaration(a,b,c))return-1

#definevardeclarationdo(a,b,c)if(-1==vardeclaration(a,b,c))return-1

#defineintegerdeclarationdo(a,b,c)if(-1==integerdeclaration(a,b,c))return-1

#definecharacterdeclarationdo(a,b,c)if(-1==characterdeclaration(a,b,c))return-1

#definedoubdeclarationdo(a,b,c)if(-1==doubdeclaration(a,b,c))return-1

voiderror(intn);

intgetsym();

intgetch();

voidinit();

intgen(enumfctx,inty,doublez);

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

intinset(inte,bool*s);

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

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

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

intblock(intlev,inttx,bool*fsys);

voidinterpret();

intfactor(bool*fsys,int*ptx,intlev);

intterm(bool*fsys,int*ptx,intlev);

intcondition(bool*fsys,int*ptx,intlev);

intexpression_r(bool*fsys,int*ptx,intlev);

intstatement(bool*fsys,int*ptx,intlev);

voidlistcode(intcx0);

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

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

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

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

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

intposition(char*idt,inttx);

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

intbase(intl,int*s,intb);

//pl0.cpp

#include<

stdio.h>

#include"

pl0.h"

string.h"

//这个宏定义的意思表示是运行时的数据栈大小,这个会在interpret函数中出现,可以先不用管它

#definestacksize500

/*********************************************************************************

**在看源程序之前,请始终记住**

**sym表示的是当前字符串的类型,**

**num表示的数字,**

**id中存放的是字符串,**

**记住这点在看源程序的时候非常重要。

**

**另外,还要记住的是nxtlev数组中存放的是后继符号集**

**********************************************************************************/

intmain()

boolnxtlev[symnum];

//这个数组表示的是当前语句的后继符号集合,一共有个

printf("

Inputpl/0file?

"

);

//输入文件的路径

scanf("

%s"

fname);

fin=fopen(fname,"

r"

//以只读打开文件,fin文件指针

if(fin)

{

Listobjectcode?

(Y/N)"

listswitch=(fname[0]=='

y'

||fname[0]=='

Y'

//listswitch用于列举代码

Listsymboltable?

tableswitch=(fname[0]=='

//tableswitch表示是否输出table表

//该表类似于页的表

fa1=fopen("

fa1.tmp"

"

w"

//以只读格式打开文件,对于本程序其实是新建一个文件

//fa1文件中存储的是源程序,运行一次,看看这个文件就明白啦

fprintf(fa1,"

//将"

输入文件中

%s\n"

//同上

init();

//初始化

err=0;

cc=cx=ll=0;

ch='

'

;

if(-1!

=getsym())

//如果程序开始是对的,则往下执行

//fa存放的是模拟程序的代码

//fas存放的是table表中的数据

//运行一次代码看一下文件即明白

fa=fopen("

fa.tmp"

//以只读形式打开

fas=fopen("

fas.tmp"

//函数原型:

//boolnxtlev[32];

/*

declbegsys[constsym]=true;

declbegsys[varsym]=true;

declbegsys[procsym]=true;

statbegsys[beginsym]=true;

statbegsys[callsym]=true;

statbegsys[ifsym]=true;

statbegsys[whilesym]=true;

执行该函数的结果为对应的下标在nxtlev中上述值均为true;

*/

//在分程序开始的时候,其后继符号可以是

//const,var,procedure,begin,call,if,while

//所以在nxtlev中将上述这些置为true

//当然在整个程序可以只有一个'

.'

,即程序是空的也可以,所以会有nxtlev[period]=true;

addset(nxtlev,declbegsys,statbegsys,symnum);

//symnum=32;

nxtlev[period]=true;

//block是编译程序的主程序,是分程序的分析处理过程,其里面调用了大部分程序

//耐心看

//请记住在block程序开始的时候,只读取了源程序的一个语句单位

if(-1==block(0,0,nxtlev))

//当程序出错的时候,则关闭以下文件,并退出程序

fclose(fa);

fclose(fa1);

fclose(fas);

fclose(fin);

\n"

return0;

}

//如果在源程序的结尾没有'

,则报错

if(sym!

=period)

error(9);

//err=0表示源程序没有错误

if(err==0)

//在源程序没有错误的前提下,打开fa2文件,依次执行里面的语句,输出源程序结果

fa2=fopen("

fa2.tmp"

//模拟计算机执行源程序

interpret();

fclose(fa2);

else

//如果远程有错的话,会这样

Errorsinpl/0program"

Can'

topenfile!

\n"

}

voidinit()

inti;

for(i=0;

i<

=255;

i++)

ssym[i]=nul;

//nul为,将ssym初始化为

//ssym大小为,可以表示所有的ASCLL码

ssym['

+'

]=plus;

-'

]=minus;

*'

]=times;

/'

]=slash;

('

]=lparen;

)'

]=rparen;

='

]=eql;

'

]=comma;

]=period;

#'

]=neq;

'

]=semicolon;

//将保留字输入word数组中,为了使用二分查找,这个设置顺序是按照字母序

/*strcpy(&

(word[0][0]),"

begin"

strcpy(&

(word[14][0]),"

character"

(word[1][0]),"

call"

(word[2][0]),"

const"

(word[3][0]),"

do"

(word[15][0]),"

doub"

(word[4][0]),"

end"

(word[5][0]),"

if"

(word[13][0]),"

integer"

(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内放有保留字所对应的枚举变量的值

wsym[0]=beginsym;

wsym[1]=callsym;

wsym[2]=charactersym;

wsym[3]=constsym;

wsym[4]=dosym;

wsym[5]=doubsym;

wsym[6]=endsym;

wsym[7]=ifsym;

wsym[8]=integersym;

wsym[9]=oddsym;

wsym[10]=procsym;

wsym[11]=readsym;

wsym[12]=thensym;

wsym[13]=varsym;

wsym[14]=whilesym;

wsym[15]=writesym;

//mnemonic中存放的是模拟程序的命令符

//大小是个,因为只有中命令符

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

//初始化这些数组,全部为false

for(i=0;

symnum;

declbegsys[i]=false;

statbegsys[i]=false;

facbegsys[i]=false;

//下面的这三块内容的功能在后续的介绍中会有,

//分别是声明开始符号集,语句开始符号集,因子开始符号集

declbegsys[integersym]=true;

declbegsys[charactersym]=true;

declbegsys[doubsym]=true;

facbegsys[ident]=true;

facbegsys[number]=true;

facbegsys[lparen]=true;

facbegsys[charnum]=true;

facbegsys[doubnum]=true;

//该函数的功能是返回符号e是否在符号集s中

//是则返回true,否则返回false

intinset(inte,bool*s)

returns[e];

//对于下标i,如果s1或s2是true,则sr也是true

//这个函数其实是初始化后继符号集,即nxtlev数组

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

n;

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全部置为空格

space[cc-1]=0;

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

****%s!

%d\n"

space,n);

err++;

intgetch()

if(cc==ll)

if(feof(fin))//fin未知

programincomplete"

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

当前位置:首页 > 人文社科 > 广告传媒

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

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