1、=;,()/*/3、其他标记是 I和 NUM,通过下列正则表达式定义:ID=ltr leter NUM=dig d*ette a|。|z|。|Z dt=0.。、空格由空白、换行符和制表符组成。空格通常被忽略,除了它必须分开 ID、NUM 关键字。5。注释用通常的 C 语言符号/.*/围起来。注释可以放在任何空白出现的位置(即注释不能放在标记内)上,且可以超过一行注释不能嵌套.DF图如下:初始状态设置为 STAR,当需要得到下一个 toke时,取得此 ten的第一个字符,并且按照 DFA 与对此字符的类型的分析,转换状态。重复此步骤,直到 DNE为止,输出okn类型。参考课本中所给的 TIN扫描
2、程序的FA,的 DFA不同之处在于注释以及(=,!=,,=)的处理:1.注释部分参考了课本中 C 风格注释的FA;Other othr */*/Or othr 2.处理(=,!=,=,=)时并没有新建状态,而是在状态 INASIG中分了种情况,通过一个变量分别处理。语法分析:C语法与语义:1 pror ecaratin-ls 2。delratiolist elaraonist eclarato|delaron 3.dclaratn rdelaraton|fu-decaratio 4.var-delato yespci I;typepcfier D NUM ;pe-speifier int|d
3、6.fun-dclartion type-pfe D(aams)compounstmt(在课后解释中 coundstmt 前面没有“|”符号)7。paras aram-lis|vid 。aralit param-list,paam am 9。aram ypespecir ID|type-specifier ID pondtmt locldeclats statemet-ist 1.lcdclrati ocaclaratons vadclaration|emty 12。statemnlist sateenst statent|empy 。ttmen exprsionstt|compu-tmt|s
4、election-stm|iteraiostmt etrnstmt 14。expresionst expresio;;sletiontt f(exreson)tatment|f(expession)tatemen else staement 6。eationstmt il(epression)atement 17。rtrnstt etun;|reur expesin;8。exprssin v=exprssion|ipleepeson 9。vr ID|ID xession 2.simplexsio additiveexpression relo aitieepress|aditivexpresi
5、on 2.relop =|#inlue SDLIB。nclude#inclde nclueiostream incld direct.h sing nmesace st;ifndef AL#efie FAL 0#endi#fndf TRUE#def TRE 1;endi /保留字的个数#dfine MAXRESRED 6 ype enu /bookkeeping tkns DIL,EROR,/eserved wod IF,ESE,NT,RETURN,VO,WILE,/ltiharact oken I,NUM,/speial ymbols /RACKTRBACKET LBCE/RBAE SIGN
6、,EQ,LT,RT,US,MINUS,IES,OVER,LPAREN,RAR,E,LBRACKT,RBRAT,NEQ,COMM,LRAE,RBRACE ,LTEQ,TEQ Tkenype;extr FE*oce;/源代码文件 extern ILE listn;/listin output text file extern FILE*coe;/extrn t lineno;/语法分析树 typedf enum Nodeind StmtK,ExpK,eclrtionK,;tpeef enu StmtKind IfK,he,Ai,RetrnK,VoidK,;typeef enm ExpKind Op
7、,ConstK,IdK,Aray_exp,FntionexpK,;typde enm xpype Voi,Intge;yede enum craonKnd FuctonK,VarK,AryK,PaaterK ;#deie MXCHLRE 3 pdef stru treeod srut teeNode elartin;strct teNoe*childMAXCHILDREN;src treeNoe*silin;struct treoe*pars;int li;odeKid nodkd;ion ind SmtKind mt;ExKin ex;DeclaratiKid declaraton;knd;
8、trct MyStruct Tokenype op;it v;char*;n se;at;pType ype;Teede;extrn int EhSourc;exte int TraceScn;eer nt TraePare;xter it TcAnaze;xr in raceCode;extr t Erro;#endi 3.2.2 can。c 最主要的过程是 GtToke,它消耗输入字符并根据 DFA图返回下一个被识别的记号。这个实现利用了双重嵌套情况分析,以及一个有关状态的大型情况列表,在大列表中是基于当前输入字符的单独列表。记号本身被定义成 gos。h 中的枚举类型。扫描程序的状态也被定
9、义为一个枚举类型,位于扫描程序之中。扫描程序使用了三个全局变量,文件变量ource,isting在 globals中声明且在 mn。c中被分配和初始化的整型变量ineno。由 gtTon过程完成的额外的簿记如下所述:表 resed 和过程reservedlooup完成位于由tToen的主要循环识别的标识符之后的保留字的查找,urrentTokn的值也随之改变。标志变量 save被用作指示是否将第一个字符增加到 tokenStrg之上;由于需要包括空白格和非消耗的先行,因此这些东西都是必要的。到扫描程序的字符输入由 gNextCha函数提供,该函数将一个 26 字符缓冲区内部的 lineBuf中
10、的字符取到扫描程序中,如果已经耗尽了这个缓冲区,且假设每一次都获取了一个新的源代码行,那么 getextChar 就利用ge从 source文件更新该缓冲区。最后由于从 INUM 和 INID到最终状态的转换是非消耗的.可以通过一个gtnxthar的过程在输入缓冲区的反填一个字符来完成这一任务.#includ”globals。h”#inclue”il.h”ncud”san。h pedef enum STAT,IASGN,INCOMMENT,NENDCMENT,INNUM,IID,DNE,LT,IRT,INEQSateType;car oknStrngMTOKNLE;#define FLEN 1
11、24 static char lineBFLEN;stt nt linpos=0;satic int bfsize=0;/geextChar 从 lineBf获得下一个非空字符,读入新的一行如果 lineBf 耗尽 sa cha gtextCHar(void)if(!(iosbufiz)lnno+;f(fges(lineBuf,BUN-1,sorce)if(EchoSourc)fint(litin,%d,%,nen,ineB);busestrlen(lieBuf);ieos=0;reu ineBulinepo+;lse eturn OF;ele return ineufnpos+;/bckrc
12、ks ne haacer i ineBuf statc oid ungeNexthar(void)linepos-;/查找表的保留字 satc strt char*sr;TknTpe t;reserveWordsAXESERVD”i,IF,”int,T,”ele,EL,rurn”,RETR,voi,VID,”whie,WHIL;/查找一个标识符,看看这是否是一个保留字/使用线性搜索 satc TokeType rsevedLookup(char)int i;or(i=0;iMARESERE;+)f(!strp(s,resrvedWords.st)reurn rserveWrds。to;retr
13、n I;okenType gtTo(id)/索引存储为“tkenStrig”int kenStnIe=0;/返回当前on oenType currenoken;/当前状态总是以ART开始 tteype stat=TR;/指示存放至 toknString的标志 int saveTRUE;whie(s!DONE)in =getNxtCHr();ave=TUE;sich(state)cae SAT:f(sgt(c)state=INNM;lse if(isalh()stae=INID;lse f(c=)stat=INASSIGN;es if(c=)|(c )|(c=n)save FLS;else if
14、(c=)/遇到”则假定就是注释,进入注释状态 state COMMEN;save FLSE;ee f(c=)stae=INRT;else (=)stat=INL;ele if(c=!)tate=INN;else tat=D;swic(c)defult:currenke EROR;eak;as EOF: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*:curr
15、entToken=TIMES;cae:curtTen=LBRACE;beak;case:rrnToken=RBRACE;case(:curntToken LPAREN;brak;cas):urrTken=RPARE;cse;:cretToken EMI;brek;eak;*=注释改动=*/case INENDCOMENT:if(=*&getextCar()=)/toke是*且下一个 tokn是/则结束注释 sve=FALSE;state=STAR;/注释不作处理,直到注释结束,lse ave FLS;tt=NNOMMENT;case IOMMET:if(c=)/“/”后是则进入注释 /ugNe
16、thar();sv FALSE;t=NDCOMMENT;/若是注释开头,转入注释结尾处理 lse if(=OF)tate=DON;crrnTo=END;else /“/”后不是*则为除法 ugetNextChar();sae=FALE;crntTokn=OVER;tae=DONE;=*/赋值改动=*/ce IASIN:ste DONE;i(c=)/下一个仍是等号就为相等 currentToke=EQ;lse 否则回退,netNtCar();save=LSE;curetTken=ASSG;bea;=*/小于等于=*/case NLT:tate DONE;if(c=)currntoke=LTEQ;
17、ele ugeNxtChar();sae FALSE;crenoke=T;brea;=/大于等于=cae NRT:sate=ONE;if(=)currentToke=RTEQ;es neNexChar();ave=FLSE;rntokn=RT;be;/*=不等于=*/ae INNEQ:stat DON;if(c=)curentToken=NQ;else ungetNextCar();sv=LE;currentToen=ERROR;cse INUM:i(!isdigt(c)ungetNetChar();se=FALE;ta=DON;curretToken=NU;ase IN:(!isapha()
18、ungtNextChar();save=FALSE;tae=ONE;crrenten=ID;bre;cae DONE:efalt:rint(lsting,”Ser Bug:state=dn”,tate);stae DON;enToen=ERROR;if(ave)&(oknSingIndex AXTKENE)oketrnoenStigInx+=(har)c;if(stae=DONE)oentrinoenSingnde=0;if(centokn=)urretTen=reservedLup(toknSig);if(TraeScan)printf(lstng,d:,lnno);printToken(c
19、urentToken,tkenString);tun cuentTken;3.23 parser.c includeloals.h”iclude”til。”#ncudecan.h”#include”prse。h”static TkenTpe tok;/lds urnt token satic TreeNode*stm_sequence(vod);tatic TreNoe tatee(oi);statc TreeNoe if_mt(vid);sta reeNode*whil_tmt(oid);/自定义函数 saic TreNod*reurtmt(vid);static TreeNoe*intst
20、(vod);saic eNoe void_sm(voi);stac Treeoe*declaaio(vod);stati rNde parameter(void);static TeeNode*xp(id);tac TreeNoe*ipleex(oi);static Treede*em(od);tt reeNode aco(void);stai voi inFuncion(vo);static d synaxrro(car message)prit(istin,”n);fprif(ist,Sntax ror at lie d:%s,ino,message);Error=TUE;stati vo
21、i ath(okenTp expected)if(toke=expecte)token=token();else syntxrr(”nepct toke”);printToe(tokn,toenStrin);fprint(litin,”);TreNoe stt_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;se p-sbi=;p=q;return t;TeNode tate
22、met(void)reeode NLL;wich(token)case IF:t=f_tmt();case WLE:wilestt();bre;cae ID:/若为D不直接进行赋值,进入 exp()至act(),将赋值加入至fator()=ex();cae ETRN:t=retur_smt();case NT:t=it_stmt();ase OID:t oid_tmt();br;case SEMI:matc(EMI);bak;dault:ntaxr(”unexpecte token );printTok(oen,okeSting);toen=getTokn();rturn t;Treee*de
23、caatin(vid)reeNod t=newDclaatioNode(tken);if(t!=L)/名称 token eto();/ID赋给 attr。name t-attr。ame=coyStrin(tokntrng);oke=getToen();/oken 是”(”则为函数声明 if(toke=LPREN)tkidecaation FunctionK;mah(LPRN);TreNoe*paramets=paraeer();/函数参数匹配 if(araes!=NLL)t-child0=parames;atch(PRN);mat(LRCE);/匹配函数体 TeeNd*bod=sttseuen
24、();if(body=NUL)sntxErr(error body!);else tchid1=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)TeeNode t=NUL;if(tken=OI)mtch(OID);/结束 else i(toen RBA
25、E)reurn t;/有参数 ele t newDecaatinNo(toke);tokn etokn();tatr。name=opySring(tokStri);toe=etToen();/数组 if(ten=LACET)tnd.clarin=AryK;match(LBRACET);tttr.ize 0;math(RRACKET);ID else t-kind。earation arK;f(oke=CMA)c();bng prametr();reurn t;TeeNode if_stmt(void)TreNoe t=newSmtNode(f);match(I);(t!=NUL)matc(LA
26、EN);tchild ex();mtch(RPREN);f(t!NULL)/如果带大括号 if(token=BRACE)mtch(LBRACE);whie(toke!=RAC)thild staemen();matc(BACE);/无括号 ese t-ci1 staeent();i(tok=ELSE)match(ELSE);f(t!=NLL)/如果带大括号 if(tken=LRACE)atch(LBRAE);RBRACE)tchild=statent();match(RBRACE);/无括号 e tchil2=taten();rer t;reeNode*hsm(v)Teede*t=ewSttN
27、oe(WhileK);atch(WHIL);Treoe =NUL;mtch(LPAREN);while(tken!=RPREN)(t-cild=NUL)p=exp();hild0=p;ele p=p-chi0;p ep();match(RPREN);/hile函数大括号可有可无/如果有括号 if(tken=LBRACE)match(LBRAC);wile(oken!=RBACE)thild1 atment();atch(RRACE);/无 ls t-child1=satemnt();f(token=SEMI)math(SEMI);retrn t;TeeNode*rtunt(void)TreNo
28、d t wSmtNoe(Ren);tattr。ame opyStig(kentring);atc(TUR);f(tke!=SEMI)t-hild0=exp();ach(SEMI);er t;reeNde inttmt(vid)TeNde*t=newDeaaonode(INT);match(INT);ne opStrn(tokStrng);mat(ID);/函数 if(token=AREN)mac(LPAREN);tkd.eclratin=FunctinK;if(toke=VOD)ath(VID);lse /函数参数匹配 inFucion();match(RREN);/函数体 mth(LBRCE
29、);wle(tken!=RRAE)stament();mac(RBRACE);数组 ese (token=LBRAKET)tindex=ArrapK;ch(BRAK);t-ild0=exp();mah(BACKET);/变量 if(oken=EMI)tkindelarain Var;mach(SEMI);/voi 函数 reNod*vo_stm(void)Tede =neDclaratiooe(VOI);ac(ID);-atr.name copyrin(knSrng);math(ID);math(LPEN);i(token=VOID)at(VOID);l inFcon();match(RPAN);match(LBRA);while(tn!ACE)stteent();mtch(RRACE);/函数参数匹配 vid inFnio(void)mtc(INT);at(I);if(oken=L
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1