1、_A-Za-z0-9_A-Za-z标识符ID整型常量INT0-9+浮点常量FLOAT0-9(.0-9+)?(E+-?0-9+)?界符DELIM,;()运算符OPT!%&*+-?/|&|=|=|字符常量CHAR$字符串常量STR$源程序:#include string.hstdlib.hctype.hstdarg.h#define KEY 0#define ID 1#define INT 2#define FLOAT 3#define CHAR 4#define STR 5#define DELIM 6#define OPT 7char *TYPE = KEY, IDINTFLOATCHARST
2、RDELIMOPT;char filename256; /要处理的文件名long length; /文件长度char *key =autobreakcasecharconstcontinue, defaultdodoubleelseenumexternfloatforgotoifintlongregister,returnshortsignedsizeofstaticstructswitchtypedefunionunsignedvoidvolatilewhile, NULL;const int KEYCOUNT = 32;char *source; /源码的内存缓冲区long pos=0;
3、/指向源码的指针long line=1; /行号long column=0; /列号char token1024; /临时存放标识符void error(const char* error, .) va_list arglist; va_start(arglist, error); vfprintf(stderr, error, arglist); va_end(arglist); exit(EXIT_FAILURE);void warning(const char* error, .) /判断是否为分隔符,是的话返回1,否则返回0int isdelim(const char ch) swit
4、ch(ch) case (:case ),; return 1; return 0;int isoperator(const char ch) +-*/=!% case |.int iskey(const char* str) for(int i=0; iKEYCOUNT; i+) if(strcmp(keyi, str) = 0) return i+1;/读入源码的一个字符char readSource() if(pos 1) 字符常量字符多余1个n%ldt%st%sn, line, TYPECHAR, token);void getString(char ch) i-;%ldt%st%s,
5、 line, TYPESTR, token);void getIdentify(char ch) int i=1; !isspace(ch = readSource(); if(isalpha(ch) | isdigit(ch) | ch = _ tokeni = ch; else if(isoperator(ch) | isdelim(ch) | ch = else error(非法标识符字符n, filename, line, column); tokeni+ = if(iskey(token), line, TYPEKEY, token);, line, TYPEID, token);v
6、oid getNum(char ch) int hasDot=0; int type=0; / 0 is int 1 is float int afterE=0; hasDot=1; type = 1; token0=ch; for(i=1;i256;i+) i = 1) if(!isdigit(ch) return;hasDot) 数字中小数点多于1个nE | ch = e afterE = 1; if(afterE) afterE = 0; else if(! strlen(token) = 1) /error(未预料的符号 .n getOperator(ch); if(type = 0)
7、 , line, TYPEINT, token); else if(type = 1) , line, TYPEFLOAT, token);/获得界符与运算符void getDelim(char ch) %ldt%st%cn, line, TYPEDELIM, ch);void lexer() pos = 0; line = 1; preprocess(); pos length; char ch = readSource(); /printf(%ld %ld %cn, line, column, ch); if(isalpha(ch) | ch = getIdentify(ch); else
8、 if(isdigit(ch) | ch = getNum(ch); else if(isspace(ch) else if(ch = getChar(ch); getString(ch); comment(); else if(isoperator(ch) else if(isdelim(ch) getDelim(ch);%ldtPREt%cn, line, ch);/* 命令行参数 * lexer filename */int main(int argc, char *argv) if (argc != 2) Usage: %s filenamen, argv0); strcpy(file
9、name, argv1); FILE* file; if (NULL = (file = fopen(argv1, r) Cannot open %s.n, filename); long fileLength = getFileLength(file); source = (char *) malloc (fileLength+1); fseek (file, 0, SEEK_SET); int hasRead; for (hasRead=0;feof(file); int count = fread (source+hasRead, 1, 1024, file); hasRead+=cou
10、nt; sourcehasRead = 0; length = hasRead; lexer(); /调用词法处理器 fclose (file);测试程序:int getSum(int num) int sum=0; while(i=num) sum += i; i+; return sum;/* This function is to get two num and calculate there sum * and print the sum of 1 2 . to 10int main() int t=10; float a=10E-5, b=5.2; scanf(%f%f, &a, &
11、b);a = %f, b = %fn, a, b); if(a = b)a is equal to bn else if(a b)a bn /invoke a functionsum = %dn, sum(t);测试结果:2 #include 3 KEY int3 ID getSum3 DELIM (3 ID num3 DELIM )3 DELIM 4 KEY int4 ID i4 OPT =4 INT 04 DELIM ;5 KEY int5 ID sum5 OPT =5 INT 05 DELIM ;6 KEY while6 DELIM (6 ID i6 OPT =6 ID num6 DEL
12、IM )6 DELIM 7 ID sum7 OPT +=7 ID i7 DELIM ;8 ID i8 OPT +8 DELIM ;9 DELIM 10 KEY return10 ID sum10 DELIM ;11 DELIM 17 KEY int17 ID main17 DELIM (17 DELIM )17 DELIM 18 KEY int18 ID t18 OPT =18 INT 1018 DELIM ;19 KEY float19 ID a19 OPT =19 FLOAT 10E-519 DELIM ,19 ID b19 FLOAT 5.219 DELIM ;21 ID scanf21
13、 DELIM (21 STR 21 DELIM ,21 OPT &21 ID a21 ID b21 DELIM )21 DELIM ;22 ID printf22 DELIM (22 STR 22 DELIM ,22 ID a22 ID b22 DELIM )22 DELIM ;23 KEY if23 DELIM (23 ID a23 OPT =23 ID b23 DELIM )24 ID printf24 DELIM (24 STR 24 DELIM )24 DELIM ;25 KEY else25 KEY if25 DELIM (25 ID a25 OPT 25 ID b25 DELIM
14、)26 ID printf26 DELIM (26 STR 26 DELIM )26 DELIM ;28 KEY else28 ID printf28 DELIM (28 STR 28 DELIM )28 DELIM ;31 ID printf31 DELIM (31 STR 31 DELIM ,31 ID sum31 ID t31 DELIM )31 DELIM ;32 KEY return32 INT 032 DELIM ;33 DELIM 实验感想:1. 开始时的程序整体无框架,所有程序都写在了一个函数里,写到中间发现不宜维护,可读性差,后来就整体重新写了一遍,把不相关的功能剥离,提高模块性及可读性。2. 开始时注释处理在符号处理后面,后来发现处理不了注释,经过排查后发现把注释处理放到最前面就行了。3. 本程序添加了许多错误处理,使代码更加健壮。
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2