编译原理课程设计C词法扫描器及语法分析器实现Word文档格式.docx
- 文档编号:16649234
- 上传时间:2022-11-25
- 格式:DOCX
- 页数:61
- 大小:409.07KB
编译原理课程设计C词法扫描器及语法分析器实现Word文档格式.docx
《编译原理课程设计C词法扫描器及语法分析器实现Word文档格式.docx》由会员分享,可在线阅读,更多相关《编译原理课程设计C词法扫描器及语法分析器实现Word文档格式.docx(61页珍藏版)》请在冰豆网上搜索。
=;
()/*/3、其他标记是I和NUM,通过下列正则表达式定义:
ID=ltrleterNUM=digd*ettea|。
|z|。
|Zdt=0.。
、空格由空白、换行符和制表符组成。
空格通常被忽略,除了它必须分开ID、NUM关键字。
5。
注释用通常的C语言符号/.*/围起来。
注释可以放在任何空白出现的位置(即注释不能放在标记内)上,且可以超过一行注释不能嵌套.DF图如下:
初始状态设置为STAR,当需要得到下一个toke时,取得此ten的第一个字符,并且按照DFA与对此字符的类型的分析,转换状态。
重复此步骤,直到DNE为止,输出okn类型。
参考课本中所给的TIN扫描程序的FA,的DFA不同之处在于注释以及(=,!
=,,=)的处理:
1.注释部分参考了课本中C风格注释的FA;
Otherothr*/*/Orothr2.处理(=,!
=,=,=)时并没有新建状态,而是在状态INASIG中分了种情况,通过一个变量分别处理。
语法分析:
C语法与语义:
1prorecaratin-ls2。
delratiolistelaraonisteclarato|delaron3.dclaratnrdelaraton|fu-decaratio4.var-delatoyespciI;
typepcfierDNUM;
pe-speifierint|d6.fun-dclartiontype-pfeD(aams)compounstmt(在课后解释中coundstmt前面没有“|”符号)7。
parasaram-lis|vid。
aralitparam-list,paamam9。
aramypespecirID|type-specifierIDpondtmtlocldeclatsstatemet-ist1.lcdclratiocaclaratonsvadclaration|emty12。
statemnlistsateenststatent|empy。
ttmenexprsionstt|compu-tmt|selection-stm|iteraiostmtetrnstmt14。
expresionstexpresio;
;
sletionttf(exreson)tatment|f(expession)tatemenelsestaement6。
eationstmtil(epression)atement17。
rtrnsttetun;
|reurexpesin;
8。
exprssinv=exprssion|ipleepeson9。
vrID|IDxession2.simplexsioadditiveexpressionreloaitieepress|aditivexpresion2.relop=|#inlueSDLIB。
nclude#incldenclueiostreaminclddirect.hsingnmesacest;
ifndefAL#efieFAL0#endi#fndfTRUE#defTRE1;
endi/保留字的个数#dfineMAXRESRED6ypeenu/bookkeepingtknsDIL,EROR,/eservedwodIF,ESE,NT,RETURN,VO,WILE,/ltiharactokenI,NUM,/speialymbols/RACKTRBACKETLBCE/RBAESIGN,EQ,LT,RT,US,MINUS,IES,OVER,LPAREN,RAR,E,LBRACKT,RBRAT,NEQ,COMM,LRAE,RBRACE,LTEQ,TEQTkenype;
extrFE*oce;
/源代码文件externILElistn;
/listinoutputtextfileexternFILE*coe;
/extrntlineno;
/语法分析树typedfenumNodeindStmtK,ExpK,eclrtionK,;
tpeefenuStmtKindIfK,he,Ai,RetrnK,VoidK,;
typeefenmExpKindOp,ConstK,IdK,Aray_exp,FntionexpK,;
typdeenmxpypeVoi,Intge;
yedeenumcraonKndFuctonK,VarK,AryK,PaaterK;
#deieMXCHLRE3pdefstrutreeodsrutteeNodeelartin;
strctteNoe*childMAXCHILDREN;
srctreeNoe*silin;
structtreoe*pars;
intli;
odeKidnodkd;
ionindSmtKindmt;
ExKinex;
DeclaratiKiddeclaraton;
knd;
trctMyStructTokenypeop;
itv;
char*;
nse;
at;
pTypeype;
Teede;
extrnintEhSourc;
exteintTraceScn;
eerntTraePare;
xteritTcAnaze;
xrinraceCode;
extrtErro;
#endi3.2.2can。
c最主要的过程是GtToke,它消耗输入字符并根据DFA图返回下一个被识别的记号。
这个实现利用了双重嵌套情况分析,以及一个有关状态的大型情况列表,在大列表中是基于当前输入字符的单独列表。
记号本身被定义成gos。
h中的枚举类型。
扫描程序的状态也被定义为一个枚举类型,位于扫描程序之中。
扫描程序使用了三个全局变量,文件变量ource,isting在globals中声明且在mn。
c中被分配和初始化的整型变量ineno。
由gtTon过程完成的额外的簿记如下所述:
表resed和过程reservedlooup完成位于由tToen的主要循环识别的标识符之后的保留字的查找,urrentTokn的值也随之改变。
标志变量save被用作指示是否将第一个字符增加到tokenStrg之上;
由于需要包括空白格和非消耗的先行,因此这些东西都是必要的。
到扫描程序的字符输入由gNextCha函数提供,该函数将一个26字符缓冲区内部的lineBuf中的字符取到扫描程序中,如果已经耗尽了这个缓冲区,且假设每一次都获取了一个新的源代码行,那么getextChar就利用ge从source文件更新该缓冲区。
最后由于从INUM和INID到最终状态的转换是非消耗的.可以通过一个gtnxthar的过程在输入缓冲区的反填一个字符来完成这一任务.#includ”globals。
h”#inclue”il.h”ncud”san。
hpedefenumSTAT,IASGN,INCOMMENT,NENDCMENT,INNUM,IID,DNE,LT,IRT,INEQSateType;
caroknStrngMTOKNLE;
#defineFLEN124staticcharlineBFLEN;
sttntlinpos=0;
saticintbfsize=0;
/geextChar从lineBf获得下一个非空字符,读入新的一行如果lineBf耗尽sachagtextCHar(void)if(!
(iosbufiz))lnno+;
f(fges(lineBuf,BUN-1,sorce))if(EchoSourc)fint(litin,%d,%,nen,ineB);
busestrlen(lieBuf);
ieos=0;
reuineBulinepo+;
lseeturnOF;
elereturnineufnpos+;
/bckrcksnehaaceriineBufstatcoidungeNexthar(void)linepos-;
/查找表的保留字satcstrtchar*sr;
TknTpet;
reserveWordsAXESERVD”i,IF,”int,T,”ele,EL,rurn”,RETR,voi,VID,”whie,WHIL;
/查找一个标识符,看看这是否是一个保留字/使用线性搜索satcTokeTypersevedLookup(char)inti;
or(i=0;
iMARESERE;
+)f(!
strp(s,resrvedWords.st))reurnrserveWrds。
to;
retrnI;
okenTypegtTo(id)/索引存储为“tkenStrig”intkenStnIe=0;
/返回当前onoenTypecurrenoken;
/当前状态总是以ART开始tteypestat=TR;
/指示存放至toknString的标志intsaveTRUE;
whie(s!
DONE)in=getNxtCHr();
ave=TUE;
sich(state)caeSAT:
f(sgt(c))state=INNM;
lseif(isalh()stae=INID;
lsef(c=)stat=INASSIGN;
esif(c=)|(c)|(c=n))saveFLS;
elseif(c=)/遇到”则假定就是注释,进入注释状态stateCOMMEN;
saveFLSE;
eef(c=)stae=INRT;
else(=)stat=INL;
eleif(c=!
)tate=INN;
elsetat=D;
swic(c)defult:
currenkeEROR;
eak;
asEOF:
sv=LE;
currentTokn=EDFI;
beak;
cas:
urenTokn=LRCE;
break;
cs:
crentTn=RCKT;
brek;
cas,:
rrntToen=OMM;
brea;
cse+:
urentToken=PUS;
se-:
currntToken=IU;
break;
ae*:
currentToken=TIMES;
cae:
curtTen=LBRACE;
beak;
case:
rrnToken=RBRACE;
case(:
curntTokenLPAREN;
brak;
cas):
urrTken=RPARE;
cse;
:
cretTokenEMI;
brek;
eak;
*=注释改动=*/caseINENDCOMENT:
if(=*&
getextCar()=)/toke是*且下一个tokn是/则结束注释sve=FALSE;
state=STAR;
/注释不作处理,直到注释结束,lseaveFLS;
tt=NNOMMENT;
caseIOMMET:
if(c=)/“/”后是则进入注释/ugNethar();
svFALSE;
t=NDCOMMENT;
/若是注释开头,转入注释结尾处理lseif(=OF)tate=DON;
crrnTo=END;
else/“/”后不是*则为除法ugetNextChar();
sae=FALE;
crntTokn=OVER;
tae=DONE;
=*/赋值改动=*/ceIASIN:
steDONE;
i(c=)/下一个仍是等号就为相等currentToke=EQ;
lse否则回退,netNtCar();
save=LSE;
curetTken=ASSG;
bea;
=*/小于等于=*/caseNLT:
tateDONE;
if(c=)currntoke=LTEQ;
eleugeNxtChar();
saeFALSE;
crenoke=T;
brea;
=/大于等于=caeNRT:
sate=ONE;
if(=)currentToke=RTEQ;
esneNexChar();
ave=FLSE;
rntokn=RT;
be;
/*=不等于=*/aeINNEQ:
statDON;
if(c=)curentToken=NQ;
elseungetNextCar();
sv=LE;
currentToen=ERROR;
cseINUM:
i(!
isdigt(c))ungetNetChar();
se=FALE;
ta=DON;
curretToken=NU;
aseIN:
(!
isapha())ungtNextChar();
save=FALSE;
tae=ONE;
crrenten=ID;
bre;
caeDONE:
efalt:
rint(lsting,”SerBug:
state=dn”,tate);
staeDON;
enToen=ERROR;
if((ave)&
(oknSingIndexAXTKENE)oketrnoenStigInx+=(har)c;
if(stae=DONE)oentrinoenSingnde=0;
if(centokn=)urretTen=reservedLup(toknSig);
if(TraeScan)printf(lstng,d:
lnno);
printToken(curentToken,tkenString);
tuncuentTken;
3.23parser.cincludeloals.h”iclude”til。
”#ncudecan.h”#include”prse。
h”staticTkenTpetok;
/ldsurnttokensaticTreeNode*stm_sequence(vod);
taticTreNoetatee(oi);
statcTreeNoeif_mt(vid);
stareeNode*whil_tmt(oid);
/自定义函数saicTreNod*reurtmt(vid);
staticTreeNoe*intst(vod);
saiceNoevoid_sm(voi);
stacTreeoe*declaaio(vod);
statirNdeparameter(void);
staticTeeNode*xp(id);
tacTreeNoe*ipleex(oi);
staticTreede*em(od);
ttreeNodeaco(void);
staivoiinFuncion(vo);
staticdsynaxrro(carmessage)prit(istin,”n);
fprif(ist,Sntaxroratlied:
%s,ino,message);
Error=TUE;
stativoiath(okenTpexpected)if(toke=expecte)token=token();
elsesyntxrr(”nepcttoke”);
printToe(tokn,toenStrin);
fprint(litin,”);
TreNoestt_seqece(voi)TreNode*t=statmen();
TreNoe*p=t;
hie(en!
=ENDFILE)&
(tke!
=BRACE))reeod*;
/h(SEMI);
q=stateet();
i(tken!
=RBRACE)f(q!
=ULL)if(t=NUL)=q;
sep-sbi=;
p=q;
returnt;
TeNodetatemet(void)reeodeNLL;
wich(token)caseIF:
t=f_tmt();
caseWLE:
wilestt();
bre;
caeID:
/若为D不直接进行赋值,进入exp()至act(),将赋值加入至fator()=ex();
caeETRN:
t=retur_smt();
caseNT:
t=it_stmt();
aseOID:
toid_tmt();
br;
caseSEMI:
matc(EMI);
bak;
dault:
ntaxr(”unexpectetoken);
printTok(oen,okeSting);
toen=getTokn();
rturnt;
Treee*decaatin(vid)reeNodt=newDclaatioNode(tken);
if(t!
=L)/名称tokeneto();
/ID赋给attr。
namet-attr。
ame=coyStrin(tokntrng);
oke=getToen();
/oken是”(”则为函数声明if(toke=LPREN)tkidecaationFunctionK;
mah(LPRN);
TreNoe*paramets=paraeer();
/函数参数匹配if(araes!
=NLL)t-child0=parames;
atch(PRN);
mat(LRCE);
/匹配函数体TeeNd*bod=sttseuen();
if(body=NUL)sntxErr(errorbody!
);
elsetchid1=bod;
mtch(RBRAE);
/toen后不是(则是变量声明else/普通变量类型tin。
dcraio=VK;
/进入数组类型if(token=LBRCKET)match(LRKT);
kid.eclaration=AK;
tat。
z=aoi(toknString);
token=getoken();
mah(RRKT);
match(SMI);
rturn;
TreeNode*aramer(id)TeeNodet=NUL;
if(tken=OI)mtch(OID);
/结束elsei(toenRBAE)reurnt;
/有参数eletnewDecaatinNo(toke);
toknetokn();
tatr。
name=opySring(tokStri);
toe=etToen();
/数组if(ten=LACET)tnd.clarin=AryK;
match(LBRACET);
tttr.ize0;
math(RRACKET);
IDelset-kind。
earationarK;
f(oke=CMA)c();
bngprametr();
reurnt;
TeeNodeif_stmt(void)TreNoet=newSmtNode(f);
match(I);
(t!
=NUL)matc(LAEN);
tchildex();
mtch(RPREN);
f(t!
NULL)/如果带大括号if(token=BRACE)mtch(LBRACE);
whie(toke!
=RAC)thildstaemen();
matc(BACE);
/无括号eset-ci1staeent();
i(tok=ELSE)match(ELSE);
f(t!
=NLL)/如果带大括号if(tken=LRACE)atch(LBRAE);
RBRACE)tchild=statent();
match(RBRACE);
/无括号etchil2=taten();
rert;
reeNode*hsm(v)Teede*t=ewSttNoe(WhileK);
atch(WHIL);
Treoe=NUL;
mtch(LPAREN);
while(tken!
=RPREN)(t-cild=NUL)p=exp();
hild0=p;
elep=p-chi0;
pep();
match(RPREN);
/hile函数大括号可有可无/如果有括号if(tken=LBRACE)match(LBRAC);
wile(oken!
=RBACE)thild1atment();
atch(RRACE);
/无lst-child1=satemnt();
f(token=SEMI)math(SEMI);
retrnt;
TeeNode*rtunt(void)TreNodtwSmtNoe(Ren);
tattr。
ameopyStig(kentring);
atc(TUR);
f(tke!
=SEMI)t-hild0=exp();
ach(SEMI);
ert;
reeNdeinttmt(vid)TeNde*t=newDeaaonode(INT);
match(INT);
neopStrn(tokStrng);
mat(ID);
/函数if(token=AREN)mac(LPAREN);
tkd.eclratin=FunctinK;
if(toke=VOD)ath(VID);
lse/函数参数匹配inFucion();
match(RREN);
/函数体mth(LBRCE);
wle(tken!
=RRAE)stament();
mac(RBRACE);
数组ese(token=LBRAKET)tindex=ArrapK;
ch(BRAK);
t-ild0=exp();
mah(BACKET);
/变量if(oken=EMI)tkindelarainVar;
mach(SEMI);
/voi函数reNod*vo_stm(void)Tede=neDclaratiooe(VOI);
ac(ID);
-atr.namecopyrin(knSrng);
math(ID);
math(LPEN);
i(token=VOID)at(VOID);
linFcon();
match(RPAN);
match(LBRA);
while(tn!
ACE)stteent();
mtch(RRACE);
/函数参数匹配vidinFnio(void)mtc(INT);
at(I);
if(oken=L
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 课程设计 词法 扫描器 语法 分析器 实现
![提示](https://static.bdocx.com/images/bang_tan.gif)