1、电子科技大学计算机学院编译原理实验语法分析/ SyntaxAnalyzer.cpp : 定义控制台应用程序的入口点。/#include #include #include #define MAX_COUNT 1024#define SIGN_UNDEFINED_ERR 1#define SIGN_REDEFINED_ERR 2#define SIGN_EXECUTE_ERR 3#define NO_SIGN_ERR 4#define SIGN_RESERVE_ERR 5#define NO_PARA_ERR 6/*types是支持类型的集合*/typedef enum integer type
2、s;/*记录变量信息的结构体*/typedef struct char vname17; char vproc17; bool vkind; types vtype; int vlev; int vadr; varRecord;/*记录过程信息的结构体*/typedef struct char pname17; types ptype; int plev; int varNum; int fadr; int ladr; int parameter; bool parameterIsDefined; proRecord;/*文法产生式如下*A:程序 A-BB:分程序 B-begin C;M en
3、dC:说明与句表 C-DCC-;DC|D:说明语句 D-E|JE:变量说明 E-integer FF:变量 F-GG:标识符 G-HGG-HG|IG|H:字母 H-a|.|z|A|.|ZI:数字 I-0|1|.|9J:函数说明 J-integer function G(K);LK:参数 K-FL:函数体 L-begin C;M endM:执行语句表 M-NMM-;NM|N:执行语句 N-O|P|Q|WO:读语句 O-read(F)P:写语句 P-write(F)Q:赋值语句 Q-F:=RR:算术表达式 R-SRR-SR|S:项 S-TSS-*TS|T:因子 T-F|U|ZU:常数 U-VV:无
4、符号整数 V-IVV-IV|W:条件语句 W-if X then N else NX:条件表达式 X-RYRY:关系运算符 Y-|=|=|Z:函数调用 Z-G(R)*/void A();void B();void C();void C_();void D();void E();void F();void G();void J();void K();void L();void M();void M_();void N();void O();void P();void Q();void R();void R_();void S();void S_();void T();void U();void
5、W();void X();void Y();void Z();/*初始化函数:从输入文件读取数据,建立各个文件,初始化全局变量*/bool init(int argc, char* argv);/*结束处理函数,将var和pro数组中的元素输出到相应文件,填充输出文件*/bool final();/*错误处理函数,参数分别为行号、错误码和错误符号*/bool error(int lineNum, int errNum, const char* sign);/*获得所处目录路径,包括最后斜杠,或者为空*/void getPath(char* in, char* out);/*获得文件名,不包括扩
6、展*/void getFilename(char* in, char* out);/*获得下一符号,true表示已到队尾,false表示还未到队尾*/bool nextToken();/*获得当前符号的下一字符,true表示已到0*/bool nextChar();/*判断变量是否已存在*/bool isVarExisted(char* vname, char* vproc, bool vkind);/*判断过程是否已存在,参数为过程名*/bool isProExisted(char* vname);/*获得下一符号,指针不变*/int getNextToken();char inputMAX
7、_COUNT17;/存放输入文件所有符号的数组int kindMAX_COUNT;int inputCount;/输入符号的数量int pToken;/指向当前输入符号int pChar;/指向当前输入符号中的当前字符varRecord currentVar;/存放当前变量的信息proRecord currentPro;/存放当前过程的信息int lineNum;/当前行号varRecord varMAX_COUNT;/存放变量名表项数组proRecord proMAX_COUNT;/存放过程名表项数组int varCount;/变量的数量int proCount;/过程的数量FILE* in
8、File;/输入文件句柄FILE* outFile;/输出文件句柄FILE* errFile;/错误文件句柄FILE* varFile;/变量文件句柄FILE* proFile;/过程文件句柄/*主函数*/int main(int argc, char* argv) if (init(argc, argv) A(); final(); return 0;bool init(int argc, char* argv) if (argc != 2) return false; else char* inFilename = argv1; char outFilenameMAX_COUNT = ;
9、char errFilenameMAX_COUNT = ; char varFilenameMAX_COUNT = ; char proFilenameMAX_COUNT = ; char filenameMAX_COUNT = ; char pathMAX_COUNT = ; /获得文件名(不包括扩展名)和路径 getFilename(inFilename, filename); getPath(inFilename, path); /生成输出文件全部路径 strcat(outFilename, path); /strcat(outFilename, ); strcat(outFilenam
10、e, filename); strcat(outFilename, .dys); /生成错误文件全部路径 strcat(errFilename, path); /strcat(errFilename, ); strcat(errFilename, filename); strcat(errFilename, .err); /生成变量文件全部路径 strcat(varFilename, path); /strcat(varFilename, ); strcat(varFilename, filename); strcat(varFilename, .var); /生成过程文件全部路径 strca
11、t(proFilename, path); /strcat(proFilename, ); strcat(proFilename, filename); strcat(proFilename, .pro); /打开文件句柄 if (inFile = fopen(inFilename, r) & (outFile = fopen(outFilename, w) & (errFile = fopen(errFilename, w) & (varFile = fopen(varFilename, w) & (proFile = fopen(proFilename, w) /初始化单词指针、字符指针、
12、行号、层次 inputCount = 0; pToken = 0; pChar = 0; lineNum = 1;/当前行号 /level = 0;/当前层次 /varCountInPro = 0; strcpy(currentPro.pname, ); currentPro.plev = 0; currentPro.varNum = 0; currentPro.parameter = -1; varCount = 0; proCount = 0; /读取输入文件内容,初始化input数组 while (!feof(inFile) char stringOfLineMAX_COUNT; if
13、(fgets(stringOfLine, MAX_COUNT, inFile) char lineString20 = ; strncpy(lineString, stringOfLine, 19); char* kindString = strrchr(lineString, ); kindinputCount = atoi(kindString+1); char string17 = ; strncpy(string, stringOfLine, 16); char* lastString = strrchr(string, ); strcpy(inputinputCount, lastS
14、tring + 1); inputCount+; return true; else fclose(inFile); fclose(outFile); fclose(errFile); fclose(varFile); fclose(proFile); return false; bool final() for (int i = 0; i varCount; i+) int vkind = vari.vkind ? 1 : 0; char* vtype = (vari.vtype = integer) ? integer : ; fprintf(varFile, %16s %16s %d %
15、s %d %dn, vari.vname, vari.vproc, vkind, vtype, vari.vlev, vari.vadr); for (int i = 0; i proCount; i+) char* ptype = (proi.ptype = integer) ? integer : ; fprintf(proFile, %16s %s %d %d %dn, proi.pname, ptype, proi.plev, proi.fadr, proi.ladr); if (fseek(inFile, 0, 0) = 0) while (!feof(inFile) fputc(f
16、getc(inFile), outFile); bool val; val = fclose(inFile); val = fclose(outFile); val = fclose(errFile); val = fclose(varFile); val = fclose(proFile); return val;bool error(int errNum,const char* symbol) char* errInfo; switch (errNum) case SIGN_UNDEFINED_ERR: fprintf(errFile, *LINE:%d %s符号无定义n, lineNum
17、, inputpToken); break; case SIGN_REDEFINED_ERR: fprintf(errFile, *LINE:%d %s符号重定义n, lineNum, inputpToken); break; case SIGN_EXECUTE_ERR: fprintf(errFile, *LINE:%d %s处不能匹配执行语句n, lineNum, inputpToken); break; case NO_SIGN_ERR: fprintf(errFile, *LINE:%d %s处缺少%sn, lineNum,inputpToken, symbol); break; ca
18、se SIGN_RESERVE_ERR: errInfo = 以保留字开头; break; case NO_PARA_ERR: fprintf(errFile, *LINE:%d 缺少形参%s的声明n, lineNum, symbol); break; default: errInfo = 未知错误; return true;void getPath(char* in, char* out) char* name; name = strrchr(in, ); if (name != NULL) strncpy(out, in, strlen(in) - strlen(name) + 1); e
19、lse strcpy(out, );void getFilename(char* in, char* out) char* fullName; char* extension; fullName = strrchr(in, ); extension = strrchr(in, .); if (fullName != NULL) strncpy(out, fullName + 1, strlen(fullName) - 1 - strlen(extension); else strncpy(out, in, strlen(in) - strlen(extension);bool nextToke
20、n() pToken+; pChar = 0; if (strcmp(inputpToken, EOF) = 0) return true; while (strcmp(inputpToken, EOLN) = 0) pToken+; lineNum+; return false;bool nextChar() if (inputpTokenpChar = 0) /nextToken(); return true; pChar+; return false;bool isVarExisted(char* vname, char* vproc, bool vkind) for (int i =
21、0; i varCount; i+) if (strcmp(vname, vari.vname) = 0) & (strcmp(vproc, vari.vproc) = 0) & (vari.vkind = vkind) return true; for (int i = 0; i proCount; i+) if (strcmp(vname, proi.pname) = 0) return true; return false;bool isProExisted(char* vname) for (int i = 0; i varCount; i+) if (strcmp(vname, va
22、ri.vname) = 0) return true; for (int i = 0; i proCount; i+) if (strcmp(vname, proi.pname) = 0) return true; return false;int getNextToken() int pNextToken = pToken + 1; while (strcmp(inputpNextToken, EOLN) = 0) pNextToken+; return pNextToken;void A() B();void B() if (strcmp(inputpToken, begin) = 0)
23、nextToken(); else error(NO_SIGN_ERR,begin); if (strcmp(inputpToken, integer)!=0) nextToken(); C(); if (strcmp(inputpToken, ;) = 0) nextToken(); else error(NO_SIGN_ERR, ;); if (strcmp(inputpToken, integer) != 0) & (strcmp(inputpToken, read) != 0) & (strcmp(inputpToken, write) != 0) & (kindpToken!=10)
24、 nextToken(); M(); if (strcmp(inputpToken, end) = 0) nextToken(); else error(NO_SIGN_ERR, end); void C() D(); C_();void C_() if (strcmp(inputpToken, ;) = 0 & strcmp(inputgetNextToken(), integer) = 0) nextToken(); D(); C_(); else if (strcmp(inputpToken, integer) = 0) error(NO_SIGN_ERR, ;); D(); C_();
25、 void D() if (strcmp(inputpToken + 1, function) = 0) J(); else E(); void E() if (strcmp(inputpToken, integer) = 0) nextToken(); else error(NO_SIGN_ERR, integer); /if (kindpToken != 10) / nextToken(); / strcpy(currentVar.vname, inputpToken); strcpy(currentVar.vproc, currentPro.pname); if (pToken = cu
26、rrentPro.parameter) currentVar.vkind = true; currentPro.parameterIsDefined = true; else currentVar.vkind = false; currentVar.vtype = integer; currentVar.vlev = currentPro.plev; currentVar.vadr = varCount; if (isVarExisted(inputpToken, currentPro.pname, currentVar.vkind)/如果存在变量 error(SIGN_REDEFINED_ERR,NULL); else if (currentPro.varNum = 0)/如果当前过程中变量数为0,则当前变量是当前过程的第一个变量 currentPro.fadr = currentVar.vadr; currentPro.ladr = currentVar.vadr;/过程中最后一个变量在变量表中的位置 currentPro.varNum+;/过程中变量数+ varvarCoun
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1