编译原理课程设计C词法扫描器及语法分析器实现Word文档格式.docx

上传人:b****4 文档编号:16649234 上传时间:2022-11-25 格式:DOCX 页数:61 大小:409.07KB
下载 相关 举报
编译原理课程设计C词法扫描器及语法分析器实现Word文档格式.docx_第1页
第1页 / 共61页
编译原理课程设计C词法扫描器及语法分析器实现Word文档格式.docx_第2页
第2页 / 共61页
编译原理课程设计C词法扫描器及语法分析器实现Word文档格式.docx_第3页
第3页 / 共61页
编译原理课程设计C词法扫描器及语法分析器实现Word文档格式.docx_第4页
第4页 / 共61页
编译原理课程设计C词法扫描器及语法分析器实现Word文档格式.docx_第5页
第5页 / 共61页
点击查看更多>>
下载资源
资源描述

编译原理课程设计C词法扫描器及语法分析器实现Word文档格式.docx

《编译原理课程设计C词法扫描器及语法分析器实现Word文档格式.docx》由会员分享,可在线阅读,更多相关《编译原理课程设计C词法扫描器及语法分析器实现Word文档格式.docx(61页珍藏版)》请在冰豆网上搜索。

编译原理课程设计C词法扫描器及语法分析器实现Word文档格式.docx

=;

()/*/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

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

当前位置:首页 > 求职职场 > 简历

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

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