1、,|;|(|)|其中l表示az中的任何一个英文字母,d表示09中的任一个数字。关键字也是一种单词,一般关键字都是由字母构成,关键字集合时标识符集合的子集。2.2 词法分析方法从待分析文件中取出当前符号ch=fgetc(fp)If(Isalpha(ch)读出字符串,放进TOKEN代码中If(Iskey(token)对不同关键字进行种别码设置else 标识符种别码设置else if(Isdigit(ch)统一设置为一种种别码数字放入TOKEN代码中else if(Isoperation(ch)对不同操作符设置不同种别码将读出的操作符放入TOKEN代码else if(Isboundrary(ch)设
2、置每种界符的种别码将读出的界符放入TOKEN代码中2.3符号表设计和TOKEN代码设计typedef struct _token_list /记录词法分析结果 Token token; struct _token_list* next;TokenNode, *PTokenList;typedef struct _symtab /符号表 char name10; /名称 char type10; /类型 int length; /长度 int offset; /相对数 struct _symtab *next;sym, *PSYMLIST;typedef struct _token /TOKEN
3、代码设计 int sym; /种别码 char str10; /存放单词*PToken, Token;3.简要分析与概要设计:设置一个TOKEN结构体,用来存放单词信息,其中包含sym和str10两个成员,sym用来存放单词种别码,str10数组用来存放单词符号。设置一个Symtab结构体,用来存放符号表中个变量的信息,其中name10用来存放单词名称,type10用来存放单词类型,length用来存放单词存储位置信息。在程序运行之前,先把要分析的程序放在一个.txt记事本中,分析过程中通过ch=fgetc(ch)从文件中读取字符,并进行分析,分析过程见2.2词法分析方法。对分析之后的单词用二
4、元式进行输出。接下来进行符号表内容的输出,将已经分析过的关键字,存放在table数组中,当遇到分析出的符号为;时,将table数组清空。对分析出的标识符进行判断,如果是第一次分析出,则用symtab.type存放其类型,用symtab.name存放其名称,symtab.length存放其长度,symtab.offset存放其相对数,然后输出符号表信息,如果不是第一次分析出,则输出错误提示。4.程序主要流程图5.源代码#define _CRT_SECURE_NO_WARNINGS /字符串和内存操作时 关闭函数的安全警告#includestdlib.hstring.hint j,n;char c
5、h;typedef struct _tokentypedef struct _token_list /记录词法分析结果char _type510 = int, floatchardoublelong; /符号表类型int _size5 = 32, 32, 8, 64, 32; /及对应的长度PSYMLIST symtab = NULL; /符号表的头指针PSYMLIST symtail = symtab; /符号表的尾指针Token token;char type10 = 0; /保存类型名称PTokenList ptl = NULL; /TokenList的头指针PTokenList ptl
6、tail = ptl; /TokenList的尾指针int LineNumber = 1; /记录代码行数int offset = 0; /计算变量偏移地址void Scan(FILE*); /词法分析bool Isoperation(char ch); /判断i当前所指的字符是否为一个运算符 bool Isboundary(char ch); /判断i当前所指的字符是否为一个分界符bool Iskey(char ch); /判断i当前所指的字符是否为关键字bool Isalpha(char ch); /判断i当前所指的字符是否为字母bool Isdigit(char ch); /判断i当前所
7、指的字符是否为数字bool IsType(char ch); /判断是否为类型int GetSizeOfType(char type); /获得类型大小int SearchSymTab(char name); /查找符号表void AddToSymTab(Token token);void PrintSymTab(); /显示符号表void AddToTokenList(Token token);/保存到词法分析表void PrintTokenList(); /显示词法分析表/主函数void main() char input20; FILE *fp; printf(*n 1022-表示关键字
8、 n 2-表示标识符 n 3-表示数字 n 4057-表示操作符 n 6065-表示界符 n*n);please input the source file name: while(true) gets(input); if(fp=fopen(input,r)!=NULL) break;/读取文件内容,并返回文件指针,该指针指向文件的第一个字符 else printf(file open filed! Please input again: n*the result is as follows*n while(!feof(fp) Scan(fp); /扫描源程序 /符号表 PrintSymTa
9、b(); /词法分析 PrintTokenList(); getchar();/暂停/判断i当前所指的字符是否为一个运算符,是的话返回真,反之假 bool Isoperation(char ch) int t; char arr8=+,*/=! for (t=0;t8;t+) if(ch=arrt) return true; return false; /判断i当前所指的字符是否为一个分界符,是的话返回真,反之假 bool Isboundary(char ch) char arr6=;() for(t=0;6; if(ch=arrt) return true; return false;/判断
10、i当前所指的字符是否为一个关键字,是的话返回真,反之假 bool Iskey(char ch) char *keywords13=const,autoifelsebreak,fordoprintfcase13;t+) if (strcmp(token.str,keywordst)=0) bool IsType(char ch) char *keywords5= for (t = 0; t 5; t +)/判断i当前所指的字符是否为字母,是的话返回真,反之假bool Isalpha(char ch) if(cha)|(ch0ch9) int GetSizeOfType(char type) fo
11、r(int i = 0; i name, token.str, 10);type, type, 10); s-length = GetSizeOfType(s-type);offset = offset; offset += s-length;next = NULL; if(symtab = NULL) /如果链表为空 则初始化链表 symtab = s; symtail = symtab; else /链表不为空则将节点增加到链表尾部 symtail-next = s; symtail = s;int SearchSymTab(char name) int exist = 0; /如果没有找
12、到 int index = -1; for(PSYMLIST s = symtab; s != NULL; s = s-next) index += 1; if(strcmp(name, s-name) = 0) exist = 1; return exist? index : -1;void PrintSymTab()符号表:n名称 类型 长度 相对数 n for (PSYMLIST s = symtab; printf(%-10s%-10s%-10d%-10dn, s-name, s-type, s-length, s-offset);void AddToTokenList(Token t
13、oken) TokenNode *tn = (TokenNode *) malloc(sizeof(TokenNode); if(tn = NULL) return; memcpy(&(tn-token), &token, sizeof(Token); tn- if(ptl = NULL) ptl = tn; ptltail = tn; else ptltail-next = tn;void PrintTokenList()词法分析表:名称 类型n for (PTokenList s = ptl;%-10s%-10dn,s-token.str, s-token.sym);void Scan(F
14、ILE *fp) token.str10=NULL; j=0; ch=fgetc(fp); /获取字符,指针fp并自动指向下一个字符 if(ch = n) LineNumber +; /记录分析的代码的行号 strcpy(type, /分析字符串 if (Isalpha(ch) /判断该字符是否是字母 while (ch = ) & (ch ) token.strj+=ch; ch=fgetc(fp); token.strj+ = 0 / 代表字符结束(空格) fseek(fp,-1,1); /回退一个字符 if(Iskey(token.str) switch(n) /关键字种别码设置 cas
15、e 0:token.sym = 10;break; case 1:token.sym = 11; case 2:token.sym = 12; case 3:token.sym = 13; case 4:token.sym = 14; case 5:token.sym = 15; case 6:token.sym = 16; case 7:token.sym = 17; case 8:token.sym = 18; case 9:token.sym = 19; case 10:token.sym = 20; case 11:token.sym = 21; case 12:token.sym =
16、 22; else token.sym = 2; /2表示标识符种别码 /printf(%d , %s)n,token.sym , token.str); AddToTokenList(token); else if(Isdigit(ch) token.sym=3; /3表示数字种别码 while(ch(ch) else if(Isoperation(ch) /运算符 switch (ch) case: token.strj= if(ch= token.sym=40; token.strj+=ch; token.strj= else token.sym=41; token.strj+ = fseek(fp,-1,1); break; token.sym=42; token.sym=43; token.strj+ = fseek(fp,-1,1); if(ch = token.sym=44; token.sym=45; token.sym=46; token.sym=47; token.sym=48; else if(ch= token.sym=49; token.sym=50;
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2